归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并排序的子操作思想:对两个有序的系列进行合并,合并的时候不断的对两个系列的第一个元素进行比较,把较小的那个移动到最前面成为了第一个元素,那么移动的元素后面的元素就是成为了下次比较的序列的第一个元素,如此不断的对两个系列的中的元素进行比较。
分析合并两个有序的过程 合并1 4 5 6 和 2 7 8 9
第一次1与2比较 1比2小, 那么1被移动了 4成为了下次要比较的元素了那么下一次就是比较4和2 2小就被移动了 那么再次比较的就是4和7了 如此一次一次的比较。
然后利用上面分析的子操作原理加上使用递归思想实现合并排序算法,具体看代码,仔细分析一下就懂了。
#include <iostream>
#include <vector>
using namespace std;
//merge two array:对两个有序列进行合并
void merge(int *a, int begin, int mid, int end, int *temp)
{
int i = begin;
int j = mid + 1;
int k = end;
int m = 0;
while (i <= mid && j <= end)
{
if (a[i] <= a[j])
temp[m++] = a[i++];
else
temp[m++] = a[j++];
}
while (i <= mid)
temp[m++] = a[i++];
while (j <= end)
temp[m++] = a[j++];
for (int i = 0; i < m; ++i)/*把存储在临时对象temp中排好序的元素copy到a中对应的下标上*/
a[begin + i] = temp[i];
}
void merge_sort(int a[], int begin, int end, int *temp)
{
if (begin < end)
{
int mid = (begin + end) / 2;
merge_sort(a, begin, mid, temp); // letf have a regular
merge_sort(a, mid + 1, end, temp); // right have a regular
merge(a, begin, mid, end, temp); //merge two in one
}
}
int main(int argc, char*argv[])
{
int a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int temp[11] = { 0 };
merge_sort(a,0, 9,temp);
for (int i = 0; i < 10; ++i)
{
cout << a[i] << endl;
}
return 0;
}