算法思想:
分治法,将一个序列分为两部分,分别排序,然后合并已排序序列。
算法实现:
1 void merge(int A[],int p,int q,int r ) 2 { 3 int * AA = new int[r-p+1]; 4 int i = p; 5 int j = q; 6 int k = 0; 7 8 while( i < q && j <= r ) 9 { 10 if( A[i] <= A[j] ) AA[k++] = A[i++]; 11 else AA[k++] = A[j++]; 12 } 13 while( i < q ) 14 { 15 AA[k++] = A[i++]; 16 } 17 while( j <= r ) 18 { 19 AA[k++] = A[j++]; 20 } 21 22 memcpy(A,AA,(r-p+1)*sizeof(int)); 23 delete []AA; 24 } 25 26 void merge_sort( int A[], int n ) 27 { 28 if( n < 2 ) return ; 29 int mid = n/2; 30 merge_sort( A, mid); 31 merge_sort( A+mid, n-mid); 32 merge( A, 0, mid, n-1 ); 33 }
考虑优化点:
- 合并时每次申请、释放内存会严重影响运行效率,可以考虑在外部传入空间用于合并操作
- 在子序列数量较小时,可以使用插入排序来优化提升效率
- 合并后将序列复制到原序列中,该操作会增加nlgn的数据复制,可以参考stl中stable_sort的实现方式,避免或减少数据复制
算法复杂度:
平均:O(nlgn)
最差:O(nlgn)
最优:O(nlgn)
空间复杂度:O(n)
使用场景:
归并排序由于有比较优的时间复杂度,并且具有排序稳定性(相同key值元素不改变位置),因此一般用在要求稳定性的大规模数据排序中。
STL实现:
stl的stable_sort内部采用了归并算法实现,在有足够归并空间时,其复杂度为O(nlgn),但当空间不足时,其复杂度为O(n lgn lgn )
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步