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

今天研究了一下比较排序算法中的归并算法和快速排序算法,这两种算法基本上都采用了分治算法的思想。首先,我们谈谈归并算法。
归并算法每次均将序列分为两半分别处理,最终合并成一个序列。归并算法可以把序列看成二叉树的根节点,序列中的元素看成树的叶节点,首先将容量为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算法。排序算法就小小的研究到这。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值