归并排序——C++
C++归并排序
分析:
归并排序是利用分治算法解决问题的典例,核心思路就是将序列不断拆分,然后将拆分后的子序列排序,然后合并为有序的序列。这也正好符合分治算法的思想:
1,分解(Divide)阶段:将整个问题划分为多个子问题。
2,递归求解(Conquer)阶段:(递归调用正在设计的算法)求解每个子问题。
3,合并(Combine)阶段:合并子问题的解,形成原始问题的解。
下面是具体分析:
首先划分子区间,划分过程类似于二分法,只不过每次划分的两个区间都要保留,该过程使用递归方法,最终划分到仅剩两个元素时比较大小排序然后返回上层,再划分另一半区域,当该区域的子序列都为有序的时候,在调用归并,归并主要是根据low和mid以及high来比较对应的关系,主要是向新的result数组中插入元素,此时需要三个元素用于记录下标的位置int i = low;int j = mid + 1;int k = low; i从low开始到mid结束。j从mid+1开始到high结束。k负责记录在result插入的元素的位置。第一阶段只需将i对应的值与j对应的值进行比较,然后在新result数组中插入,第二阶段当i或者j到达了自己的结束位置时便停止比较,未到结束位置的元素只需要把到结束位置这个区间的值复制到result数组中即可。比如i先到mid,那么只需将j到high区间的值追加到result数组中,或者j先到high,那么只需将i到mid区间的值追加到result数组中。大家不必担心会不会影响序列的有序性,因为mid两侧的序列都是已经经过一部分的归并排序,所以mid两侧的序列都是有序的,所以只不过第一阶段就是在一个有序的序列中插入元素使其仍有序的过程罢了。
下面附上源码:
#include<iostream>
using namespace std;
void Msort(int data[], int result[], int low, int high);
void Merge(int a[], int b[], int low, int mid, int high);
int main()
{
int data[100] = {1,3,2,4,6,5,9,8,7,10};//排序该序列
int result[100];
Msort(data, result, 0, 9);
for (int i = 0; i < 10; i++)
{
cout<< data[i] <<" ";
}
}
void Msort(int data[], int result[], int low, int high)
{
int mid;
if (high - low == 1)//子序列中只有两元素进行比较
{
if (data[low] > data[high])
{
int t = data[low];
data[low] = data[high];
data[high] = t;
}
return;
}
else if (high == low)//子序列只有一个元素时直接返回
{
return;
}
else
{
mid = (low + high) / 2;
Msort(data, result, low, mid);//继续划分子区间,分别对左右子区间进行排序
Msort(data, result, mid + 1, high);
Merge(data, result, low, mid, high); //开始归并已经排好序的start到end之间的数据
for (int i = low; i <= high; i++)//把排序后的区间数据复制到原始数据中去
{
data[i] = result[i];
}
}
}
void Merge(int data[], int result[], int low, int mid, int high)
{
int i = low;
int j = mid + 1;
int k = low;
/*第一阶段*/
while (i <= mid && j <= high)
{
if (data[i] <= data[j])
{
result[k++] = data[i++];
}
else
{
result[k++] = data[j++];
}
}
/*第二阶段*/
while (i <= mid)
{
result[k++] = data[i++];
}
while (j<=high)
{
result[k++] = data[j++];
}
}
上一篇: 归并排序(C)
下一篇: 西湖牛肉羹的家常做法,你会几种