归并排序是一种基于分治法的一种排序方法。它将要排序的序列分成两个长度相等的子序列,为每一个子序列进行排序,然后再将子序列合并成一个有序的序列。
实现:
- void _MergeSort(int *a,int begin,int end,int *tmp)
- {
- int mid = ((begin^end) >> 1) + (begin&end);
- if (mid > begin)
- _MergeSort(a,begin,mid,tmp);
- if (mid + 1 < end)
- _MergeSort(a,mid+1,end,tmp);
- int begin1 = begin;
- int end1 = mid;
- int begin2 = mid + 1;
- int end2 = end;
- int index = begin;
- while(begin1<=end1&&begin2<=end2) //先将归并时的元素放到辅助数组中,如果放到原数组的话有可能会覆盖掉其他元素产生错误
- {
- if (a[begin1] < a[begin2])
- {
- tmp[index++] = a[begin1++];
- }
- else
- {
- tmp[index++] = a[begin2++];
- }
- }
- while(begin1 <= end1)
- {
- tmp[index++] = a[begin1++];
- }
- while (begin2 <= end2)
- {
- tmp[index++] = a[begin2++];
- }
- while (begin <= end) //将辅助数组中的元素再拷贝到原数组中
- {
- a[begin] = tmp[begin++];
- }
- }
- void MergeSort(int *a,int begin,int end)
- {
- assert(a);
- int *tmp = new int[end-begin+1];
- _MergeSort(a,begin,end,tmp);
- delete[] tmp;
- }
优化:
当划分的子区间的元素小于13个元素左右时,再使用归并的话会效率不会很高,相当于多增加了二叉树的后面几层的结点。这时候我们改用直接插入排序来进行优化。
- void _MergeSort(int *a,int begin,int end,int* tmp)
- {
- int mid = ((begin^end) >> 1) + (begin&end);
- if (begin<mid)
- {
- if (mid - begin>13)
- {
- _MergeSort(a, begin, mid, tmp);
- }
- else
- {
- InsertSort(a+begin, end - begin + 1);
- }
- }
- if (mid + 1 < end)
- {
- if (end - mid - 1 > 13)
- {
- _MergeSort(a,mid+1,end,tmp);
- }
- else
- {
- InsertSort(a+mid+1,end-mid);
- }
- }
- int begin1 = begin;
- int end1 = mid;
- int begin2 = mid + 1;
- int end2 = end;
- int index = begin;
- while (begin1 <= end1&&begin2 <= end2)
- {
- if (a[begin1] < a[begin2])
- tmp[index++] = a[begin1++];
- else
- tmp[index++] = a[begin2++];
- }
- while (begin1 <= end1)
- tmp[index++] = a[begin1++];
- while (begin2 <=end2)
- tmp[index++] = a[begin2++];
- while(begin<=end)
- {
- a[begin] = tmp[begin++];
- }
- }
- void MergeSort(int* a,int begin,int end)
- {
- assert(a);
- int *tmp = new int[end-begin+1];
- _MergeSort(a,begin,end,tmp);
- delete[] tmp;
- }