简谈算法之:并归排序(Merge Sort)
2014-09-29 10:33
253 查看
并归排序是分治算法的入门级算法,其中又包含了递归的要素。其核心思想是把一个待排序的集合或者说成是数组平分成两部分排序,先排好左边的再排好右边的,最后合并两个有序子数组形成最后有序的数组。只要将这个思想递归使用便完成了我们的并归排序了。
对于算法刚入门的人来说,我想并归排序是一个相当有意思的算法,也许会问:“怎么就先排左边再排右边,最后合起来就得到要排序的数组呢?”,是的笔者当年也是为这个问题想了很久,很费解。到后来笔者是这样理解,首先并归排序他是递归的那么理解递归好的办法是从底至顶理解。什么是递归的底呢?那一定是递归停止条件。
在并归排序的递归停止条件就是,当数组只有一个元素的时候停止递归开始返回,设这样递归位置为LOW1,比这高的位置设为为LOW2,这个递归位置包含两个LOW1的返回(一个左边一个右边即LOW2有两个元素),以此类推。对于并归排序,可以推算出总共有N个LOW1,N/2个LOW2,N/4个LOW3....,而这个编号最大等于lgN。
而理解并归排序关键起始是LOW2层,在这一层里我们有两个LOW1,我们可以认为是两个已经排好续的数组,那么我们可以很方便的在Θ (n)时间内将两个数组合并,如下面代码中的Merge函数,一旦完成Merge,则合并的有序数组作为LOW2的返回到LOW3层。在LOW3层重复Merge方法并将有序数组作为返回到LOW4。一直这个过程直到返回至第一次调用,此时便已经得到排序好的数组。
接下来我们分析并归排序的算法复杂度。对于LOW1因为只有一个元素所以为Θ (1),而总计有N个LOW1,所以算法在LOW1层总计花销 N*Θ (1) = Θ (N),对于LOW2有两个元素需要合并则耗时Θ (2),总计N/2个LOW2,则LOW2层花费N/2*Θ (2)=Θ (N),如此我们总计有lgN个Θ (N),所以最后的并归排序的时间复杂度为lgN*Θ (N)=
Θ (NlgN)。
对于算法刚入门的人来说,我想并归排序是一个相当有意思的算法,也许会问:“怎么就先排左边再排右边,最后合起来就得到要排序的数组呢?”,是的笔者当年也是为这个问题想了很久,很费解。到后来笔者是这样理解,首先并归排序他是递归的那么理解递归好的办法是从底至顶理解。什么是递归的底呢?那一定是递归停止条件。
在并归排序的递归停止条件就是,当数组只有一个元素的时候停止递归开始返回,设这样递归位置为LOW1,比这高的位置设为为LOW2,这个递归位置包含两个LOW1的返回(一个左边一个右边即LOW2有两个元素),以此类推。对于并归排序,可以推算出总共有N个LOW1,N/2个LOW2,N/4个LOW3....,而这个编号最大等于lgN。
而理解并归排序关键起始是LOW2层,在这一层里我们有两个LOW1,我们可以认为是两个已经排好续的数组,那么我们可以很方便的在Θ (n)时间内将两个数组合并,如下面代码中的Merge函数,一旦完成Merge,则合并的有序数组作为LOW2的返回到LOW3层。在LOW3层重复Merge方法并将有序数组作为返回到LOW4。一直这个过程直到返回至第一次调用,此时便已经得到排序好的数组。
接下来我们分析并归排序的算法复杂度。对于LOW1因为只有一个元素所以为Θ (1),而总计有N个LOW1,所以算法在LOW1层总计花销 N*Θ (1) = Θ (N),对于LOW2有两个元素需要合并则耗时Θ (2),总计N/2个LOW2,则LOW2层花费N/2*Θ (2)=Θ (N),如此我们总计有lgN个Θ (N),所以最后的并归排序的时间复杂度为lgN*Θ (N)=
Θ (NlgN)。
void Meage(int *pArry, int iP, int iMid, int iQ) { int iNum = iQ - iP + 1; if(pArry[iMid] < pArry[iMid + 1])return ;//运气很好,两个子数组是有序的 int *pTmp = new int[iNum]; int tmp; int i = iP; int j = iMid + 1; int k = 0; for (;i <= iMid && j <= iQ;) { if (pArry[i] < pArry[j]) { pTmp[k++] = pArry[i++]; } else { pTmp[k++] = pArry[j++]; } } if(i > iMid) { memcpy(pTmp + k, pArry + j , sizeof(int) * (iQ - j + 1)); } else if (j > iQ) { memcpy(pTmp + k, pArry + i , sizeof(int) * (iMid - i + 1)); } memcpy(pArry + iP, pTmp, sizeof(int) * iNum); delete []pTmp; } void MeageSort(int *pArry, int iP, int iQ) { if(iP == iQ) return;//停止递归的条件 int iMid = (iP + iQ) / 2; //排左边 MeageSort(pArry, iP, iMid); //再排右边 MeageSort(pArry, iMid + 1, iQ); //合并两个子数组 Meage(pArry, iP, iMid, iQ); }
相关文章推荐
- 【DS】排序算法之归并排序(Merge Sort)
- 算法第三次作业(1. 排序。对文件 largeW.txt(下载链接)中的数据,编程实现冒泡排序(方法名:bubbleSort) 与 归并排序(mergeSort),把排序后的结果分别保存到largeW
- 基础排序算法之并归排序(Merge Sort)
- 插入排序(insert_sort)与 并归排序(merge_sort) 算法分析
- 数据结构和算法分析之排序篇--归并排序(Merge Sort)和常用排序算法时间复杂度比较(附赠记忆方法)
- 算法-排序-归并排序(MergeSort)分析
- linux下归并排序(MergeSort)算法的C语言实现
- NSort,支持10种泛型排序的算法类
- 归并排序(Merge sort)算法
- 归并排序(merge sort)算法实现
- Merge Sort [Basic] C程序 实现排序功能
- 算法不会,尚能饭否之排序——直接插入排序(Insert sort)
- Merge Sort 并且返回逆序数的算法 - C#实现
- 算法 - 排序 - 直接选择排序(Straight Selection Sort)
- 分治法排序 Thinking in MergeSort
- 【数据结构与算法基础】几种典型的排序算法 / Typical sort algorithms
- 归并排序(merge sort)算法实现
- 快速排序与快速选择算法(quick sort and quick select algorithm)
- 【数据结构与算法基础】单链表及其应用基数排序 / Singly Linked List and radix sort
- Algorithms: Merge Sort -- 归并排序