专利名称:一种基于快速排序算法的快速分页排序方法
技术领域:
本发明属于智能信息处理技术领域,具体涉及一种基于快速排序算法的快速分页排序方法。
背景技术:
排序是计算机进行信息处理的基本功能,应用范围极为广泛,特别是在信息检索、数据库系统、数据分析和数据挖掘中被大量使用。
目前,用计算机进行内部排序的主要方法是基于对关键字的比较和交换两种操作,基于这一思想的各种排序方法中以快速排序算法(Quick Sort)具有最佳的平均特性,其时间复杂度为0(N log2N),并已接近理论下界。(Donald E.Knuth.The art of computer programming(J)Sorting andSearching,Addison Wesley Publishing Company,Inc.,Vo3,1973145~158)快速排序算法的基本思想是基于分治的策略,对于输入的子序列L[p..r],如果规模足够小则直接进行排序,否则分三步处理第一步,分解将输入的序列L[p..r]划分成两个非空子序列L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于L[q+1..r]中任一元素的值。
第二步,递归求解通过递归调用快速排序算法分别对L[p..q]和L[q+1..r]进行排序。
第三步,合并由于对分解出的两个子序列的排序是就地进行的,所以在L[p..q]和L[q+1..r]都排好序后不需要执行任何计算Lp..r]就已排好序。
近年来由于需要处理的数据量越来越大,为了进一步提高排序速度,许多新的排序方法被提出,如Flash Sort、分段快速排序、分档排序(王向阳.一种新的二次分“档”链接排序算法。计算机研究与发展,2000年,37(8)1012~1017)和B-快速排序算法(陈清华、朱红、杨静宇一种B-快速排序算法计算机工程2002年,28(2)(96-99))等。他们的基本思想是借助“分配”和“收集”两种操作对关键字进行排序,这些算法可以在0(n)时间内完成对n个记录的排序。但是,这些算法或者对排序关键字类型、分布等方面有约束或者要求大量的额外存储空间,例如二次分档排序不适用于随机无符号实数序列等。上述内容见文献“分档定位排序以及向分档定位查找的发展”(陈启星、罗启宇,计算机研究与发展,2 003年,40(5)(706-711))及“数据等概率分档排序算法有效性的定量研究”(尤志强、张大方,计算机学报2003年,26(1)(46-50))从应用角度来看,不但待排序的数据集越来越大,而且对系统的快速响应要求越来越高。但是在实际应用中,往往并不要求数据集是完全有序的,而只要求数据集在指定范围内的数据与完全排序时是一致的即可,本文称之为“分页排序”。例如在信息检索系统对检索结果集进行排序分页显示中,对一次检索的结果集,找出按某一排序要求排序输出结果第101条到第120条的信息。从应用角度来说,此时仅要求输出的结果是按要求排序的第101条到第120条,其他数据条目是否有序没有任何要求,但从现有的方法来看,在对所有数据完全排序之前难以知道指定范围内包括哪些数据及它们之间的顺序,所以现有技术是对所有数据先进行完全排序,然后输出指定范围的数据子集,这必然存在大量不必要的计算开销。
发明内容
针对现有技术中存在的缺陷,本发明的目的是提出一种快速分页排序方法,该方法能针对海量数据环境下的分页排序问题,减少不必要的计算开销,避免重复计算,提高系统的响应速度。
为达到以上目的,本发明采用的技术方案是一种基于快速排序算法的快速分页排序方法,包括以下步骤一种基于快速排序算法的快速分页排序方法,包括以下步骤1)检查根据输入的待排序的序列L[p…r]与指定排序范围[first,last]检查缓存区信息;如果是第一次对输入序列进行分页排序的话,则初始化缓存区信息;2)选择针对待排序的序列L[p..r]选择一个键值,本方法中将该键值称为分解点;3)分解利用分解点将序列L[p..r]划分成两个非空子序列区间L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于分解点,而且L[q+1..r]中任一元素的值不小于分解点;也就是使L[p..q]中任一元素的值不大于L[q+1..r]中任何元素的值;4)缓存将分解点信息存储到缓存区,以便步骤1检查缓存区信息时使用;5)分析判断分解点所在位置与指定范围[first,last]的关系,决定步骤3形成的两个子序列区间哪个需要递归排序或者两个都需要递归排序,并进入第6步;6)递归如果有需要排序的子区间,则选取其中一个需要递归排序的子序列区间形成新的分页排序条件,从第1步开始新的循环;如果没有需要排序的子区间则进入第7步;7)合并对所有子序列区间的结果集进行合并,分页排序完成。
更进一步,为了使本发明具人更好的效果,在递归循环过程中,在第1步进行缓存区信息检查时,先进行待排序序列的长度的检查,如果长度小于12的话,则采用直接排序算法进行完全排序,并将相关信息存入缓存区,结束本次循环过程,然后直接进入第6步。
在检查缓存区信息时,可以判断待排序范围[first,last]在本次循环递归之前的排序过程中已经有序,更进一步的判断方法是如果序列L[p..r]中存在分解点或已完全排序的区间,则可根据这些分解点或已排序区间将序列L[p..r]分成多个子序列区间,并根据待排序范围[first,last],仅对那些与该区间有关的子序列进行排序。
再进一步,在本发明第2步中,分解点选择L[p]、L[r]、L[p+r/2]三个数值中大小中间的那个。本发明第4步中,缓存区保存各次递归循环中的分解点和完全排序的数据信息,即存储序列L中各数据位置、是否已排序、是否是分解点,其采用的数据结构可以是与待排序序列对应的数组,也可以是链表结构。本发明第5步中判断步骤3形成的两个子序列区间是否需要排序的方法可以是如果分解点在排序范围[first,last]中,则第3步形成的两个子序列区间都需要需要递归排序;如果分解点v在排序范围[first,last]左边(v<first),则子序列区间[v,r]需要递归排序,否则子序列区间[p,v]需要递归排序。
本发明的效果在于本发明所述的方法能有效地解决海量数据环境下的分页排序问题,大大减少了不必要的计算开销,避免了重复计算,提高计算机系统的响应速度。实验表明,在数据总量在数万到数百万情况下本发明的算法比快速排序算法的方法快十倍左右,而且随着数据总量的增加,这一优势越明显。
本发明之所以具有以上的效果,是因为本发明在进行排序处理时,采用类似于快速排序算法(Quick Sort)分治的策略,不断将待排序数据分成两组,并满足条件两组数据中一组的任何数据都不小于另一组中的任何数据,从而可获知这两组数据在排序结果中的位置范围(但两组数据中具体数据的位置还是未知的)。通过递归地执行这一过程,不断将不属于指定范围内的元素排除,避免了对全部数据的完全排序,避免了现有技术中大量不必要的计算。同时,通过利用基于线索(Hints)的缓存机制,避免多次分页排序的重复计算。这一方法中,计算机系统只需要很小的额外空间(小于Θ(n)),将排序的时间复杂度降低到接近Θ(n)(复杂度分析在本文中不做推导),而且对待排序数据集在数据特征上没有任何额外的要求。
图1是本发明所述方法的流程图;图2是当分页区间大小为100时的比较次数随数据总量的变化图;图3是当分页区间大小为100时的数据交换次数随数据总量的变化图;图4是当分页区间大小为100时的(比较次数/数据总量)随数据总量的变化图;图5是当数据总量为1000000时数据比较次数随分页区间大小的变化图;图6是当数据总量为1000000时数据交换次数随分页区间大小的变化图;图7是当分页区间大小为100时的比较次数随分页排序次数的变化图。
具体实施例方式
因为分页排序概念在本领域是首次提出的,为明确本发明所解决的问题,对分页排序问题进行形式化的定义如下定义“分页有序”对集合{Aj},如果集合中元素的关键字Ki,满足如下公式,则称集合{Aj}在区间[first,last]分页有序。
其中1≤first≤last≤N定义“分页排序”对于集合{Aj},所谓对{Aj}在区间[first,last]进行分页排序就是对集合中元素重新组织,使新的有序集合在区间[first,last]分页有序。
下面结合附图对本发明的具体实施方式
做进一步的描述。
如图1所示,本发明所述的一种基于快速排序算法的快速分页排序方法包括以下基本步骤
1)选择为输入的序列L[p..r]选择分解点Kv,一种可能的选择方法是选择L[p]、L[r]、L[p+r/2]三个数值中大小中间的那个;2)分解利用分解点Kv将序列L[p..r]划分成两个非空子序列L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于Kv,而且L[q+1..r]中任一元素的值不小于Kv;也就是使L[p..q]中任一元素的值不大于L[q+1..r]中任一元素的值;3)分析判断分解点Kv所在位置与指定范围[first,last]的关系,并进行递归求解;4)递归通过递归调用,分别进行子集合分页排序;5)合并对子集合的结果集进行合并。
以上基本算法可以快速完成分页排序,但是如果对已经经过分页排序的集合,当需要再次对同一数据集的另一区域进行分页排序时,如果不进行额外处理的话,已排序区域及分解点元素会因没有被标示而无法被区别对待,从而在排序过程中可能因数据交换而破坏已有的排序。
针对这一问题,本发明提出基于Hints的缓存机制,其基本方法是在算法中采用一个数组作为Hints,将每次分解的分解点以及已被定位的元素进行标识,在分析阶段利用该信息缩小递归的数据范围并避免破坏已排序元素。
为严格地描述方法的核心内容的细节,下面是用C++语言描述本发明的核心内容(采用Hints缓存机制的快速分页排序方法)。
在不影响本文核心内容的前提下,为方便代码阅读,下述代码中Hints采用数组方式标识每个位置上元素的状态,高效的算法实现中可使用其它更高效的数据结构。
<pre listing-type="program-listing">/***在集合DataList[low,high]中对范围[first,last]分页排序***/Void Quick Sort Page With Hint(Data List Type Data List,int low,int high,intfirst,int last){Init Hints(Hints,last);If(is Orderd(Data List,first,last))return; //检查Hints缓存区,避免重复计算int first_new=first;while(Hints[first_new]==IS_DISORDER)first_new++;int last_new=last;<dp n="d5"/>while(Hints[last_new]==IS-DISORDER)last_new--;int low_new=first;while(Hints[low_new]==IS_DISORDER)low_new--;int high_new=last;while(Hints[high_new]==IS_DISORDER)high_new++;//检查需排序的范围,减少不必要的计算开销,if(first_new>last) return Quick Sort Page With Hint Sub(Data List,low_new,high_new-1,first,last,Hints);else{//(first_new<=last)Quick Sort Page With Hint Sub(DataList,low_new,first_new-1,first,first_new-1,Hints);Quick Sort Page With Hint Sub(Data List,last_new,high_new-1,last_new,last,Hints);if(first_new<last_new){ Quick Sort Page With Hint Sub(Data List,first_new,last_new-1,Hints); } }}Void Quick Sort Page With Hint Sub(Data List Type Data List,int low,inthigh,int first,int last,byte* Hints){//规模足够小则直接进行排序if(high-low<mThreshold) Insertion Sort And Set Tags(Data List,low,high); else{ int cut=partition(Data List,low,high+1);//分解 Hints[cut]=IS_CUT; if(cut<=first) //分析//递归 Quick Sort Page With Hint Sub(Data List,cut,high, first,last,Hints); else if(cut>last) Quick Sort Page With Hint Sub(Data List,low,cut-1,first,last, Hints); else{<dp n="d6"/>Quick Sort Page With Hint Sub(Data List,low,cut-1,first,cut-1,Hints); Quick Sort Page With Hint Sub(Data List,cut,high,cut,last,Hints);} }}</pre>本实施例在普通PC上进行实验,CPU为P41.8G,内存为512M,Windows2000操作系统。
1)初始化如果是第一次对输入序列进行分页排序的化则初始化Hints缓存区等信息,否则检查Hints缓存区信息,以便缩小序列的范围,避免重复计算;2)规模检查序列规模,本实施例中如果序列规模小于12的话,采用冒泡排序算法进行直接排序;3)选择为输入的序列L[p..r]选择分解点Kv,本实施例中选择L[p]、L[r]、L[p+r/2]三个数值中大小中间的那个;4)分解利用分解点Kv将序列L[p..r]划分成两个非空子序列L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于Kv,而且L[q+1..r]中任一元素的值不小于Kv;也就是使L[p..q]中任一元素的值不大于L[q+1..r]中任一元素的值;5)缓存将分解点信息存储到Hints缓存区,以便步骤1使用;6)分析判断分解点Kv所在位置与指定范围[first,last]的关系,减少不必要的计算开销;7)递归通过递归调用,分别进行子集合分页排序;8)合并对子集合的结果集进行合并。
实验中采用随机数生成算法自动获得实数集合。
为避免软硬件环境对实验结果的影响,实验结果以数据比较次数和数据交换次数进行记录并对比分析。由于实验数据的数据比较次数与数据交换次数的曲线及相互关系具有很大的相似性,本文对部分实验结果仅给出数据比较次数相关的图表。
首先在不同数据总量下将快速排序算法与本发明的方法进行对比,如图2和图3所示。实验结果表明两种方法的数据比较次数与数据交换次数曲线类似,但本发明方法明显比快速排序算法的方法快。
为更清楚地看出两种方法的效率关系,我们进一步分析“比较次数与数据总量的比值”随数据总量的变化关系,如图4所示。图中数据表明,在数据总量在数万到数百万情况下,本发明方法明显比快速排序算法的方法快十倍左右,而且随着数据总量的增加,这一优势越明显。
下面我们进一步分析分页区间大小m对算法效率的影响,如图5和图6所示。在数据总量为1百万的情况下,当分页区间大小m<<数据总量n时(实验中m<n/100),比较次数与交换次数随m值的改变没有明显变化,符合算法时间复杂度降低到接近Θ(n)的分析结论。
为检验本发明方法中的Hints缓存机制的有效性,我们在1百万数据总量上,以100为分页区间进行试验,实验中对全部10000个分页区间采用随机逐个选取进行分页排序,实验结果如图7所示。结果表明随着选取次数的增加,数据比较次数迅速下降,证实了Hint缓存机制的有效性。
权利要求
1.一种基于快速排序算法的快速分页排序方法,包括以下步骤1)检查根据输入的待排序的序列L[p..r]与指定排序范围[first,last]检查缓存区信息;如果是第一次对输入序列进行分页排序的话,则初始化缓存区信息;2)选择针对待排序的序列L[p..r]选择一个键值,本方法中将该键值称为分解点;3)分解利用分解点将序列L[p..r]划分成两个非空子序列区间L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于分解点,而且L[q+1..r]中任一元素的值不小于分解点;也就是使L[p..q]中任一元素的值不大于L[q+1..r]中任何元素的值;4)缓存将分解点信息存储到缓存区,以便步骤1检查缓存区信息时使用;5)分析判断分解点所在位置与指定范围[first,last]的关系,决定步骤3形成的两个子序列区间哪个需要递归排序或者两个都需要递归排序,并进入第6步;6)递归如果有需要排序的子区间,则选取其中一个需要递归排序的子序列区间形成新的分页排序条件,从第1步开始新的循环;如果没有需要排序的子区间则进入第7步;7)合并对所有子序列区间的结果集进行合并,分页排序完成。
2.如权利要求1所述的一种基于快速排序算法的快速分页排序方法,其特征在于在递归循环过程中,在第1步进行缓存区信息检查时,先进行待排序序列的长度的检查,如果长度小于12的话,则采用直接排序算法进行完全排序,并将相关信息存入缓存区,结束本次循环过程,然后直接进入第6步。
3.如权利要求1所述的一种基于快速排序算法的快速分页排序方法,其特征在于,在递归循环过程中,在第1步检查缓存区信息时,可以采用的方法是如果序列L[p..r]中存在分解点或已完全排序的区间,则可根据这些分解点或已排序区间将序列L[p..r]分成多个子序列区间,并根据待排序范围[first,last],仅对那些与该区间有关的子序列进行排序。
4.如权利要求1所述的一种基于快速排序算法的快速分页排序方法,其特征在于第2步中,分解点选择L[p]、L[r]、L[p+r/2]三个数值中大小中间的那个。
5.如权利要求1所述的一种基于快速排序算法的快速分页排序方法,其特征在于第4步中,缓存区保存各次递归循环中的分解点和完全排序的数据信息,即存储序列L中各数据位置、是否已排序、是否是分解点,其采用的数据结构可以是与待排序序列对应的数组,也可以是链表结构。
6.如权利要求1所述的一种基于快速排序算法的快速分页排序方法,其特征在于第5步中判断步骤3形成的两个子序列区间是否需要排序的方法可以是如果分解点在排序范围[first,last]中,则第3步形成的两个子序列区间都需要递归排序;如果分解点v在排序范围[first,last]左边(v<first),则子序列区间[v,r]需要递归排序,否则子序列区间[p,v]需要递归排序。
全文摘要
本发明涉及一种基于快速排序算法的快速分页排序方法。现有的排序方法在对所有数据完全排序之前难以知道指定范围内包括哪些数据及它们之间的顺序,所以现有技术是对所有数据先进行完全排序,然后输出指定范围的数据子集,这必然存在大量不必要的计算开销,影响了计算机系统的响应速度。本发明所述的方法主要是采用类似快速排序算法(Quick Sort)分治的策略,利用缓存机制,不断将不属于指定范围内的元素排除,并逐渐排序定位指定范围内的数据,从而解决了快速分页排序的问题。采用本发明所述的方法,能有效地解决海量数据环境下的分页排序问题,大大减少了不必要的计算开销,避免了重复计算,提高了计算机系统的响应速度。
文档编号G06F17/30GK1581162SQ20041000475
公开日2005年2月16日 申请日期2004年3月3日 优先权日2004年3月3日
发明者杨建武, 陈晓鸥, 吴於茜 申请人:北京大学, 北京北大方正技术研究院有限公司