复习数据结构:排序算法(四)

基本思想:基于分治法,即把待排序的数组序列,分为若干个子序列,对每个子序列排序,然后再把所有有序的子序列合并为一个整体有序的序列。分析可知,如果拿任何一个元素作为子序列,那么所有子序列就已经是有序的,而归并排序的关键就在于如何合并,也就是“归并”。

归并排序是外排序,稳定排序,时间复杂度是O(nlogn).

详细说归并排序的过程:1个元素的表总是有序的。所以对n个元素的待排序列,每个元素可看成1个有序子表。对子表两两合并生成n/2个子表,所得子表除最后一个子表长度可能为1 外,,其余子表长度均为2。再进行两两合并,直到生成n 个元素按关键码有序的表。

代码如下:

非递归实现:(经过调试,该程序有bug,后续修正!)

#include<iostream>using namespace std; void Merge(int* r, int* rf, int i, int m, int n){int j, k; for(j = m+1, k = i; i <= m && j <= n; k++) // i记录第一个子序列标记,j记录第二个子序列标记,k记录合并后序列标记{if(r[j] < r[i]) // 存入较小者rf[k] = r[j++]; elserf[k] = r[i++]; }while(i <= m) // 如果不等长,就会出现这种情况rf[k++] = r[i++]; while(j <= n)rf[k++] = r[j++]; for(int ii = 0; ii < n+1; ii++)cout<<rf[ii]<<' '; cout<<endl; }void MergeSort(int* r, int* rf, int length){int len = 1; int* q = r; //int* tmp; while(len < length){int s = len; len = 2*s; // 等长的两个子序列,长度相同int i = 0; bool flag = true; while(i + len <= length) // 等长的两个子序列合并{cout<<"等长"<<i<<'-'<<i+s-1<<'-'<<i+len-1<<endl;Merge(q, rf, i, i+s-1, i+len-1); // 注意起始位置的标记i += len; // 下一次合并的起始flag = false; }if(i + s <= length) // 不等长两个子序列合并{cout<<"不等长"<<i<<'-'<<i+s-1<<'-'<< length-1<<endl;Merge(q, rf, i, i+s-1, length-1); // 注意最后的结束标记位置}cout<<"flag="<<flag<<endl; if(!flag)swap(q, rf); // 交换指针,该次合并的结果作为下次合并的起始}}int main(){int a[10] = {11,1,5,7,2,4,9,6,10}; // ,9,6,10,8int b[10]; MergeSort(a, b, 9); for(int i = 0; i< 9; i++)cout<<b[i]<<' '; cout<<endl; return 0; }

递归实现:

void MSort(ElemType *r, ElemType *rf,int s, int t) {ElemType *rf2;if(s==t) r[s] = rf[s];else{int m=(s+t)/2;/*平分*p 表*/MSort(r, rf2, s, m);/*递归地将p[s…m]归并为有序的p2[s…m]*/MSort(r, rf2, m+1, t);/*递归地将p[m+1…t]归并为有序的p2[m+1…t]*/Merge(rf2, rf, s, m,t); /*将p2[s…m]和p2[m+1…t]归并到p1[s…t]*/} } void MergeSort_recursive(ElemType *r, ElemType *rf, int n) { /*对顺序表*p 作归并排序*/MSort(r, rf,0, n-1); }

参考:

看自家总在期待,不知将来好歹,新乐吧总在不断等待,

复习数据结构:排序算法(四)

相关文章:

你感兴趣的文章:

标签云: