快速排序

快速排序

最坏情形时间复杂度\(\mathrm{O}(N^2)\)
平均运行时间\(\mathrm{O}(NlogN)\)

//快速排序驱动程序
void QuickSort(int  *a; int N)
{
    Qsort(a, 0, N - 1);
}

//实现三数中值分割法的程序
int Median3(int *a, int Left, int Right)
{
    int Center = (Left + Right) / 2;

    if (a[Left] < a[Center]) swap(&a[Left], &a[Center]);
    if (a[Left] < a[Right]) swap(&a[Left], &a[Right]);
    if (a[Center] < a[Right]) swap(&a[Center], &a[Right]);

    swap(&a[Center], &a[Right - 1]);
    return a[Right - 1];
}

//快速排序主例程
#define Cutoff 3

void Qsort(int *a, int Left, int Right)
{
    int i, j;
    int Pivot;

    if (Left + Cutoff <= Right)
    {
        Pivot = Median3(a, Left, Right);
        i = Left;
        j = Right - 1;
        for (; ; )
        {
            while (a[++i] < Pivot) {}
            while (a[--j] > Pivot) {}
            if (i < j) swap(&a[i], &a[j]);
            else break;
        }
        swap(&a[i], &a[Right - 1]);

        Qsort(a, Left, i - 1);
        Qsort(a, i + 1, Right);
    }
    else InsertionSort(a + Left, Right - Left + 1);//做一次插入排序
}
  1. 该算法通过选取一个枢纽元,然后使数组的剩余部分大于枢纽元的在一侧,小于枢纽元的在另一侧,然后对两边使用同样的方法,就是这样使用递归的操作是的整个数组有序
  2. 算法的移动策略大致如图:
  • 假如初始数组为8,1,4,9,6,3,5,2,7,0然后选取6为枢纽元,然后将枢纽元与数组最后一个元素交换
  • 然后使用两个指针iji从第一个元素开始,j从倒数第二个元素开始
8149035276
i↑-------j↑-
  • i向右移动,将j向左移动,当i指向的数字大于枢纽元时停下,当j指向的数字小于枢纽元时停下
8149035276
i↑------j↑--
  • 此时若ij的左边,则交换两个元素
2149035876
i↑------j↑--
  • 经过若干次这样的操作后i指针将跑到j指针的右边
2145039876
-----j↑i↑---
  • 此时ij已交错,故不再交换,此时将枢纽元与i指向的元素交换,至此就完成了一次快速排序
2145036879
-----j↑i↑---

3 示例代码中的三数中值分割法是将a[Left],a[Right]a[Center]先进行排序,得到适当的枢纽元且在交换后返回,ij也从Left + 1Right - 2开始判断

转载于:https://www.cnblogs.com/Anthony-ling/p/11355301.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值