快速排序浅谈

快速排序浅谈

一、            快速排序简述

快速排序是一种使用了分治思想的排序方法,但是具体思路和同样使用分支思想的归并排序又有着许多的不同之处。对于一个包含n个数的输入数组来说,快速排序的最坏情况时间复杂的为o(n^2)。尽管快速排序的最坏情况时间复杂度很高,但是它的平均性能非常好:它的期望时间复杂度是o(n log n),而且快速排序期望复杂度的常数因子很小。另外,它还能够进行原址排序,甚至在虚存环境也可以进行工作。

二、            快速排序的描述

题目:使用快速排序对于n的数组进行排序

         步骤:

                   分解:将数组A[b..e]划分A[b..m-1]和A[m+1..e]使得A[b..e-1]中的每一个元素都小于A[m],而A[m]也小于等于A[m+1..e]中的每个元素。

                   解决:通过递归调用快速排序,对子数组A[b..m-1]和A[m+1..e]进行排序。

                   合并:因为子数组都是原址排序的,所以不需要合并操作

                  

         例子:n=8

                   6       9       3       7       10     2       5       4

快速排序第一轮排序

A

6

9

3

7

10

2

5

4

B

6

9

3

7

10

2

5

4

C

3

6

9

7

10

2

5

4

D

3

6

9

7

10

2

5

4

E

3

6

9

7

10

2

5

4

F

3

2

6

9

7

10

5

4

G

3

2

6

9

7

10

5

4

H

3

2

4

6

9

7

10

5

 

#include"stdafx.h"

 

void quicksort(inta[], intbegin, intend)

{

    int i = begin;

    int j = end;

    int temp = a[i];

 

    if (begin < end)

    {

        while (i < j)

        {

            while ((a[j] >= temp)&& (i < j))

            {

                j--;

            }

            a[i] = a[j];

            while ((a[i] <= temp)&& (i < j))

            {

                i++;

            }

            a[j] = a[i];

        }

        a[i] = temp;

        quicksort(a, begin, i - 1);

        quicksort(a, j + 1, end);

    }

    else

    {

        return;

    }

}

 

void main()

{

    int n;

    scanf_s("%d", &n);

    int arry[1000] = { 0 };

   

    for (int i = 0; i < n;i++)

        scanf_s("%d", &arry[i]);

   

    quicksort(arry,0, n);

   

   

    for (int i = 0; i<n; i++)

    {

        printf("%6d", arry[i]);

    }

    printf("\n");

}

 

如同这样 快速排序通常使用递归的方法经过多步排序最终达到结果。但是也同样出现了一些问题,比如我们取了数组中最后一位4,但我们明显发现比4小的数只有几个。如果变成最坏情况则会更加麻烦,甚至速度与冒泡、选择排序还要低速。快速排序的运行时间依赖于划分是否平衡,而平衡与否又依赖与用于划分的元素。如果划分是平衡的,那么快速排序算法性能与归并排序一样。如果划分不平衡的,那么快速排序的性能就接近插入排序了。

所以我们分析一下最坏、最好情况:

最坏情况:当划分产生两个子问题分别包含了n-1个元素和0个元素时,快速排序的最坏情况发生了。既然是最坏情况,及假设一种每次调用都会遇见不平衡划分。划分操作的时间复杂度o(n)。由于对于一个大小为0的数组进行递归调用会直接返回,因此T(0)=o(1),于是算法运行时间的递归式可以表示为:

T(n)=T(n-1)+T(0)+o(n)=T(n-1)+o(n)

从直观上看,每一层递归的代价可以被累加起来,从而得到一个算法级数,其结果为o(n^2)。实际上,利用代入法可以直接得到递归式T(n)=T(n-1)+o(n)的解为T(n)=o(n^2)。

最好情况:在可能的最平衡的划分中,函数得到的两个子问题的规模都不大于n/2。这是因为其中一个子问题的规模[n/2],而另一个子问题的规模为[n/2]-1。在这种情况下,快速排序的性能非常好。此时,算法运行时间的递归式为:

T(n)=2T(n/2)+o(n)

在上式中,我们忽略了一些余项以及减1操作的影响。根据主定理的情况2,上述递归式的解为T(n)=o(nlogn)。通过在每一层递归中都平衡划分子数组,我们得到了一个渐近时间上更快的算法。                                 摘要《算法导论》

 

  快速排序随机思想

         在讨论快速排序的平均情况性能的时候,我们的前提假设是:输入数据的所有排序都是等概率的。但在实际工程中,这个假设的成立条件体现的并不明显,所以我们需要自己引入随机变量的思想,通过使用随机变量的方法,使算法获得一个较好的期望

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值