目录
简介
归并排序属于一种分治法,简单来说就是将一个大问题分解成若干类似大问题的子问题,然后分别解决,最后进行合并。
一般的分治法分为如下步骤:
1、分解:把一个问题分解成若干更小的类似的子问题
2、解决:递归解决子问题。当子问题足够小时,按照基础情况求解
3、合并:把子问题的解合并成原问题的解
那么将分治法应用于排序中,步骤如下:
若将一个含有n个元素的数组进行排序
1、分解:一个大问题是从1到n进行排序,那么我们将其分解,选取其中一段,从p到r进行排序。我们找到p与r的中点,反复分解。
2、解决:对p到q位置的数字进行上述递归排序,从q+1到r同理。当少于两个数字需要排序时,就会产生基础情况,因为一个数字显然是不用排序的。
3、合并:对从p到q的数列和q+1到r的数列进行合并。
代码与实操
经过上述分析,我们需要两个函数:分解函数与合并函数
分解
if (start < end) {//如果start>= end 那这段数组至多有一个元素,那么无需排序
int mid = (start + end) / 2;
Mergesort (origin,start,mid);
Mergesort (origin,mid + 1,end);
Merge (origin,start,mid,end);
}
}
合并
首先提供一下合并思路:
我们有一个数列a[p~r]
,我们将其分为两部分x[p~mid]
和y[mid+1~r]
令i
和j
分别取p
和mid+1
令k
从p
到r
依次取值
若x[i] <= y[j]
则a[k] = x[i]
,且i++
代码如下:
int fir[10001] = {INT_MAX };
int sec[10001] = {INT_MAX };
for (int i = start; i <= mid; i++) {
fir[i] = origin[i];
}
for (int i = mid + 1; i <= end; i++) {
sec[i] = origin[i];
}
int n1 = start;
int n2 = mid + 1;
for (int k = start; k <= end; k++) {
if ((n1<=mid&&fir[n1] <= sec[n2])||(n2>end)) {//这里的判定非常重要,要考虑到两边取完数的情况
origin[k] = fir[n1];
n1++;
}
else {
origin[k] = sec[n2];
n2++;
}
}
}
代码
#include <bits/stdc++.h>
using namespace std;
int a[1000001] = { };
int ans[10000001] = { };
int left = 0, right = 0;
int n = 0;
void Merge (int origin[],int start,int mid,int end) {
int fir[10001] = {INT_MAX };
int sec[10001] = {INT_MAX };
for (int i = start; i <= mid; i++) {
fir[i] = origin[i];
}
for (int i = mid + 1; i <= end; i++) {
sec[i] = origin[i];
}
int n1 = start;
int n2 = mid + 1;
for (int k = start; k <= end; k++) {
if ((n1<=mid&&fir[n1] <= sec[n2])||(n2>end)) {
origin[k] = fir[n1];
n1++;
}
else {
origin[k] = sec[n2];
n2++;
}
}
}
void Mergesort (int origin[],int start,int end){
if (start < end) {
int mid = (start + end) / 2;
Mergesort (origin,start,mid);
Mergesort (origin,mid + 1,end);
Merge (origin,start,mid,end);
}
}
int main () {
scanf ("%d/n" ,&n);
for (int i = 1;i <= n; i++) {
cin >> a[i];
}
Mergesort(a,1,n);
for (int i = 1;i <= n; i++) {
printf ("%d " ,a[i]);
}
return 0;
}
标签:origin,归并,end,int,基础,mid,start,排序
From: https://www.cnblogs.com/Crazyman-W/p/17683682.html