浅谈比较排序算法中的归并排序算法和快速排序算法

来源:互联网 发布:syntax评分软件中文版 编辑:程序博客网 时间:2024/05/18 21:48

今天研究了一下比较排序算法中的归并算法和快速排序算法,这两种算法基本上都采用了分治算法的思想。首先,我们谈谈归并算法。
归并算法每次均将序列分为两半分别处理,最终合并成一个序列。归并算法可以把序列看成二叉树的根节点,序列中的元素看成树的叶节点,首先将容量为n的序列分为两个序列,递归拆分,直到容量为1,此时再逆序排序合并。
eg:
这里写图片描述
算法思路如下:
1.如果容量为1,则退出排序,程序结束
2.递归对a1,a2,….a[n/2]排序
3.递归对a[n/2]+1,….an排序
4.合并两个有序列,得到最终的排序结果。
代码实现:

//归并排序void Merge(int sourceArr[], int tempArr[], int startIndex, int midIndex, int endIndex){    int i = startIndex, j = midIndex + 1, k = startIndex;    while (i != midIndex + 1 && j != endIndex + 1)    {        if (sourceArr[i] > sourceArr[j])            tempArr[k++] = sourceArr[j++];        else            tempArr[k++] = sourceArr[i++];    }    while (i != midIndex + 1)        tempArr[k++] = sourceArr[i++];    while (j != endIndex + 1)        tempArr[k++] = sourceArr[j++];    for (i = startIndex; i <= endIndex; i++)        sourceArr[i] = tempArr[i];}void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex){    int midIndex;    if (startIndex < endIndex)    {        midIndex = (startIndex + endIndex) / 2;        MergeSort(sourceArr, tempArr, startIndex, midIndex);        MergeSort(sourceArr, tempArr, midIndex + 1, endIndex);        Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);    }}

归并排序把大容量序列的排序划分成多个小容量的排序工作,这在算法复杂度和时间上都具有很高的性价比,但是多次递归调用函数会占用一定的计算机资源,在使用归并排序时还应注意递归的结束条件,否则会出现不可估量的错误。
最后谈谈快速排序算法,它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序算法动画演示:
这里写图片描述
(原动画摘抄至:http://blog.chinaunix.net/uid-26404477-id-3329885.html)
算法思路:
1.选择一个阈值,将比阈值小的对象放在子序列a中,将比阈值大的对象放在子序列b。
2.递归对子序列a继续排序
3.递归对子序列b继续排序。
4.连接所有排序的子序列,得到最终的排序结果。
代码如下:

//快速排序算法void quick_sort(int *a, int left, int right){    if (left >= right)    {        return;    }    int i = left;    int j = right;    int key = a[left];    while (i < j)                            {        while (i < j && key <= a[j])        {            j--;        }        a[i] = a[j];        while (i < j && key >= a[i])        {            i++;        }        a[j] = a[i];    }    a[i] = key;    quick_sort(a, left, i - 1);    quick_sort(a, i + 1, right);}

快速排序的关键在于阈值的选择,一般讲阈值选择为排序序列的某个对象,但是如果不幸选择了序列的最大值或者最小值,则退化为冒泡排序,这样效率将大大降低,在理想情况下,阈值应该选择为序列的中位数,但是精确的找到中位数一般会比较复杂,有一种比较好的解决方案是取第一个对象,中间的对象,和最后的对象的中位数,这样可以有效的避免阈值出现极大或者极小的情况。
最后,比较了一下冒泡排序,梳排序,归并排序,快速排序这几种排序算法的效率。
这里写图片描述
这里写图片描述
这里写图片描述
真正在程序里使用排序算法,可以直接调用函数库,对于复杂的数据排序一般使用几种算法组合在一起,例如内省排序和Timsort算法。排序算法就小小的研究到这。

0 0
原创粉丝点击