归并排序

将两个或者两个以上的有序表组合成一个新的有序表。假定待排序表有n个记录,则可以看成是n个有序的子表,每个子表长度为1,然后两两归并,得到[n/2]个长度为2或者1的有序表;然后两两归并,。。。如此重复,直到合并成一个长度为n的有序表为止,这个就是2-路归并排序。

Merge()的功能就是将前后相邻的两个有序表归并为一个有序表的算法。设两段有序表A[low...mid], A[mid+1...high]存放在同一顺序表中相邻的位置上,先将它们复制到辅助数组B中。每次从对应B中的两个段取出一个记录进行关键字的比较,将较小者放入A中,当数组B中有一段超出其表长时,将另一段中的剩余部分直接复制到A中。
  1. ElemType* B=(ElemType *)malloc((n+1)*sizeof(ElemType));//辅助数组B
  2. void Merge(ElemType A[], int low, int mid, int high)
  3. {
  4. //表A的两段A[low...mid]he A[mid+1...high]各自有序,将他们合并成一个有序表
  5. for(int k=low; k<=high; k++)
  6. {
  7. B[k]=A[k];//将A中所有元素复制到B中
  8. }
  9. for(i=low, j=mid+1, k=i; i<mid && j<=high; k++)
  10. {
  11. if(B[i]<=B[j])//比较B的左右两段中的元素
  12. {
  13. A[k]=B[i++];//较小的值复制到A中
  14. }else{
  15. A[k]=B[j++];
  16. }
  17. }
  18. while(i<=mid)
  19. A[k++]=B[i++];//若第一个表未检测完,复制
  20. while(j<=high)
  21. A[k++]=b[j++];//若第二个表未检测完,复制
  22. }
一趟归并排序的操作是,调用[n/2h]次算法merge()将L[1...n]中前后相邻且长度为h的有序段进行两两归并,得到前后相邻/长度为2h的有序段,整个归并排序需要进行[log2n]趟。
  1. void MergeSort(ElemType A[], int low, int high)
  2. {
  3. if(low<high)
  4. {
  5. int mid=(low+high)/2;//从中间划分两个子序列
  6. MergeSort(A,low, mid);//对左侧子序列进行递归排序
  7. MergeSort(A, mid+1, high);//对右侧序列进行递归排序
  8. Merge(A, low, mid, high);//归并
  9. }
  10. }
时间复杂度:o(nlog2n)
稳定排序




posted @ 2015-08-22 18:23  Lucas_1993  阅读(191)  评论(0编辑  收藏  举报