php专区

 首页 > php专区 > PHP进阶 > 算法 > 快速排序里的学问:快速排序的过程

快速排序里的学问:快速排序的过程

分享到:
【字体:
导读:
         摘要:通过前面问题以及引入了“信息熵”的概念,我们可以重新来理解排序的本质:一组未排序的N个数字,它们一共有N!种重排,其中只有一种排列是满足题意的(譬如从大到小排列)。换句话说,排序问题的可能性一共有N!种。任何基于比较的排序的基本操作单元都是“比较a和b”,这就相当于猜数字游戏里面的一个问句。 ...

快速排序里的学问:快速排序的过程

通过前面问题以及引入了“信息熵”的概念,我们可以重新来理解排序的本质:

一组未排序的N个数字,它们一共有N!种重排,其中只有一种排列是满足题意的(譬如从大到小排列)。

换句话说,排序问题的可能性一共有N!种。任何基于比较的排序的基本操作单元都是“比较a和b”,这就相当于猜数字游戏里面的一个问句,显然这个问句的答案只能是“是”或“否”,一个只有两种输出的问题最多只能将可能性空间切成两半,根据上面的思路,最佳切法就是切成1/2和1/2(将数组切成一半)。也就是说,我们希望在比较了a和b的大小关系之后,如果发现a b也是剩下N!/2种可能性。

由于假设每种排列的概率是均等的,所以这也就意味着支持a b的也是N!/2个,换言之,a b的概率。

我们希望每次在比较a和b的时候,a b的概率是均等的,这样我们就能保证无论如何都能将可能性缩小为原来的一半的最优下界。

一个直接的推论是,如果每次都像上面这样的完美比较,那么N个元素的N!种可能排列只需要log2N!就排查完了,而log2N!近似于NlogN。这正是快排的复杂度。

快速排序的实现

我们先理解一下快速排序的工作机制吧,下面是《算法导论》里的快排:

QUICKSORT(A, p, r)
 if p 

快速排序算法的关键是PARTITION过程,它对A[p..r]进行就地重排:

PARTITION(A, p, r)
  x ← A[r]
  i ← p - 1
  for j ← p to r - 1
       do if A[j] ≤ x
             then i ← i + 1
                  exchange A[i] <-> A[j]
  exchange A[i + 1] <-> A[r]
  return i + 1

我们将上面的过程用C语言描述一下:

#include "stdio.h"
#include "math.h"
#include "stdlib.h"

void PrintArray(int *arr);
void swap(int *a,int *b);

int num = 10;

void QuickSort(int *arr, int beg, int end)
{
	if(beg 

初始数组:59 40 55 92 73 69 27 79 3 30
    sentinel = arr[9] = 30
    arr[6](27) 

从程序的运行结果我们就可以很清晰地看出快速排序的工作工程:

  1. 定点sentinel设为数组最后一个元素30
  2. 把比30小的划成一个小组(27,3,30),并把它们放在数组的前面。
  3. 定点sentinel设为小组的最后一个,不包含30,即(27,3)中的3。
  4. 对小组原地排序,即(3,27)。这样就完成这个小组的排序了(3,27,30)。
  5. 定点sentinel再次设为数组最后一个元素55。
  6. 把小于55的元素找出来划分为另外的小组(40)。
  7. 那个小组的排序也已经完成(40,55)。
  8. 定点再设为73,同样分组(69,59,73),排序为(59,69,73)。
  9. 定点再设为79,分组(79)
  10. 完成排序:3 27 30 40 55 59 69 73 79 92

总结下快排的过程:随机选择一个元素做“轴元素”(上面的定点sentinel),将所有小于轴元素的移到左边,其余移到右边。根据这个过程,快排的第一次比较就是将一个元素和轴元素比较,这个时候显而易见的是,“大于”和“小于”的可能性各占一半。这是一次漂亮的比较。

延伸阅读

此文章所在专题列表如下:

  1. 快速排序里的学问:从猜数字开始
  2. 快速排序里的学问:再看看称球问题
  3. 快速排序里的学问:信息熵
  4. 快速排序里的学问:快速排序的过程
  5. 快速排序里的学问:霍尔与快速排序
  6. 快速排序里的学问:霍尔快排的实现
  7. 快速排序里的学问:枢纽元选择与算法效率
  8. 快速排序里的学问:随机化快排

本文地址:http://www.nowamagic.net/librarys/veda/detail/2390,欢迎访问原出处。

快速排序里的学问:快速排序的过程
分享到:
快速排序里的学问:霍尔与快速排序
快速排序里的学问:霍尔与快速排序 上一篇介绍了排序的本质,还有实现了《算法导论》里的快速排序算法。但是快速排序的算法不是只有一个,我们要一次过把快速排序的好东西都挖掘出来。所以这篇文章,让我们对快速排序溯源,去了解快速排序算法的发明者。 霍尔(Hoare) 霍尔 (Sir Charles Antony Richard Hoare) ...
编程之美2.3笔记:寻找发帖“水王”
编程之美2.3笔记:寻找发帖“水王” 《编程之美》2.3: Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当 前论坛上所有帖子...
  •         php迷,一个php技术的分享社区,专属您自己的技术摘抄本、收藏夹。
  • 在这里……