程序 QUICKSORT(A,p,r)
输入 A:一个数组 p,r:A的某个子数组的开始索引和末尾索引
结果 子数组A[p,r]中的元素按照非递减顺序排序
步骤:
1.如果p>=r,那么无需执行任何操作即可返回
2.否则,执行如下操作:
A.调用PARTITION(A,p,r),令q被赋值为PARTITION(A,p,r)的返回值
B.递归调用QUICKSORT(A,p,q-1)
C.递归调用QUICKSORT(A,q+1,r)
快速排序的关键是划分数组。
以排书本顺序为例,选择集合中最右侧的书籍(在位置r上的书籍)作为主元。
任意时刻,每本书被精确地划分到下面四个组中的一个组中,且这些组均位于位置p到位置r之间,从左到右依次是:
a.组L(左侧组):这些书籍的作者名字按照字母排序出现在主元之前或者跟主元的作者名字一致。
b.组R(右侧组):排在组L之后,这些书籍的作者名字按照字母顺序出现在主元之后。
c.组U(未知组):排在组R之后,这些书籍还没有检查,因此不知道它们的作者名字与主元的作者名字相比,排序如何。
d.组P(主元):排在组U之后,仅仅一本书,即主元。
我们从左到右检查组U中的书籍,将其与主元比较,并将它移动到组L或组R中,一旦检查到主元位置处,即终止所有操作,因此,与主元比较的始终是组U中最左侧的书籍。
接下来分类讨论:
1.如果这个书籍的作者名字按照字母排序位于主元的作者名字之后,那么这本书就成为组R中最右侧的书籍。由于这本书原来是组U中最左侧的书籍,并且组U紧跟在组R之后,所以只需要将组R和组U之间的分割线向右移动一个位置,而无需移动其余任何书籍
2.如果这个书籍的作者名字按照字母排序位于主元的作者名字之前,或者等于主元的作者名字,那么将这本书置为组L中最右侧的书籍。将它与组R中最左侧的书籍进行调换,并且将组L和组R之间的分割线向右移动一个位置
一旦判定到主元位置,将它与组R中最左侧的书籍进行调换。
为了将划分书籍的操作转换成划分一个子数组A[p......r]的操作,首先我们选择将A [r](最右侧的书籍)作为主元。随后自左向右检查子数组,将每个元素与主元进行比较
具体:
1.子数组A[p......q-1]:对应于组L:每个元素小于或等于主元
2.子数组A[q......u-1]:对应于组R:每个元素均大于主元
3.子数组A[u......r-1]:对应于组U:未知情况
4.元素A[r]对应于组P:该位置上放置着主元
在每一步中,将组U中最左侧的元素A[u]和主元进行比较。
具体:
1.如果A[u]比主元大,那么将u自增一来将组R和组U之前的分割线向右移动一个位置。
2.反之,如果A[u]小于等于主元,那么将元素A[q](组R中的最左侧元素)和A[u]进行调换,且分别将q和u自增一,相当于将组L和组R之间的分割线以及组R和组U之间的分割线分别向右移动一个位置
由上可写出PARTITION函数:
程序 PARTITION(A,p,r)
输入 A:一个数组
p,r:A的某个子数组的开始索引和末尾索引
结果 重排A[p.......r]中的元素以便A[p......q-1]中的元素均小于等于A[q]的值,同时令A[q+1......r]中的元素均大于A[q]的值。将索引q返回给调用者。
步骤
1.令q取p
2.令u从p到r-1依次取值:
如果A[u]<=A[r],那么交换A[q]和A[u]的后置,再将q自增一
3.交换A[q]和A[r]的值,返回q。
新闻热点
疑难解答