快速排序算法改进
Ⅰ Arrays.sort浣跨敤镄勬帓搴忕畻娉
鐩存帴寮闂ㄨ佸北
蹇阃熸帓搴忎富瑕佹槸瀵瑰摢浜涘熀链绫诲瀷鏁版嵁锛坕nt,short,long绛夛级鎺掑簭锛 钥屽悎骞舵帓搴忕敤浜庡瑰硅薄绫诲瀷杩涜屾帓搴忋备娇鐢ㄤ笉钖岀被鍨嬬殑鎺掑簭绠楁硶涓昏佹槸鐢变簬蹇阃熸帓搴忔槸涓岖ǔ瀹氱殑锛岃屽悎骞舵帓搴忔槸绋冲畾镄
褰掑苟鎺掑簭鐩稿硅岃█姣旇缉娆℃暟姣斿揩阃熸帓搴忓皯锛岀Щ锷锛埚硅薄寮旷敤镄勭Щ锷锛夋℃暟姣斿揩阃熸帓搴忓氾纴钥屽逛簬瀵硅薄𨱒ヨ达纴姣旇缉涓鑸姣旂Щ锷ㄨ楁椂銆傝ˉ鍏呬竴镣瑰悎骞舵帓搴忕殑镞堕棿澶嶆潅搴︽槸n logn, 蹇阃熸帓搴忕殑骞冲潎镞堕棿澶嶆潅搴︿篃鏄痭 logn锛屼絾鏄钖埚苟鎺掑簭镄勯渶瑕侀濆栫殑n涓寮旷敤镄勭┖闂淬
婧愮爜涓镄勫揩阃熸帓搴忥纴涓昏佸仛浜嗕互涓嫔嚑涓鏂归溃镄勪紭鍖栵细
銆銆1锛夊綋寰呮帓搴忕殑鏁扮粍涓镄勫厓绱犱釜鏁拌缉灏戞椂锛屾簮镰佷腑镄勯榾鍊间负7锛岄噰鐢ㄧ殑鏄鎻掑叆鎺掑簭銆傚敖绠℃彃鍏ユ帓搴忕殑镞堕棿澶嶆潅搴︿负0(n^2)锛屼絾鏄褰撴暟缁勫厓绱犺缉灏戞椂锛屾彃鍏ユ帓搴忎紭浜庡揩阃熸帓搴忥纴锲犱负杩欐椂蹇阃熸帓搴忕殑阃掑綊镎崭綔褰卞搷镐ц兘銆
銆銆2锛夎缉濂界殑阃夋嫨浜嗗垝鍒嗗厓锛埚熀鍑嗗厓绱狅级銆傝兘澶熷皢鏁扮粍鍒嗘垚澶ц嚧涓や釜鐩哥瓑镄勯儴鍒嗭纴阆垮厤鍑虹幇链鍧忕殑𨱍呭喌銆备緥濡傚綋鏁扮粍链夊簭镄勭殑𨱍呭喌涓嬶纴阃夋嫨绗涓涓鍏幂礌浣滀负鍒掑垎鍏冿纴灏嗕娇寰楃畻娉旷殑镞堕棿澶嶆潅搴﹁揪鍒疠(n^2).
銆銆3锛夋牴鎹鍒掑垎鍏 v 锛屽舰鎴愪笉鍙桦纺 v* (
婧愮爜涓阃夋嫨鍒掑垎鍏幂殑鏂规硶:
銆1锛夊綋鏁扮粍澶у皬涓 size=7 镞 锛屽彇鏁扮粍涓闂村厓绱犱綔涓哄垝鍒嗗厓銆俰nt n=m>>1;(姝ゆ柟娉曞煎缑鍊熼壌)銆
銆2锛夊綋鏁扮粍澶у皬size澶т簬7灏忎簬绛変簬40镞讹纴鍙栭栥佷腑銆佹汤涓変釜鍏幂礌涓闂村ぇ灏忕殑鍏幂礌浣滀负鍒掑垎鍏冦
銆3锛夊綋鏁扮粍澶у皬 size>40 镞 锛屼粠寰呮帓鏁扮粍涓杈冨潎鍖镄勯夋嫨9涓鍏幂礌锛岄夊嚭涓涓浼涓鏁板仛涓哄垝鍒嗗厓銆
銆鏅阃氱殑蹇阃熸帓搴忕畻娉曪纴缁忚繃涓娆″垝鍒嗗悗锛屽皢鍒掑垎鍏冩帓鍒扮礌缁勮缉涓闂寸殑浣岖疆锛屽乏杈圭殑鍏幂礌灏忎簬鍒掑垎鍏冿纴鍙宠竟镄勫厓绱犲ぇ浜庡垝鍒嗗厓锛岃屾病链夊皢涓庡垝鍒嗗厓鐩哥瓑镄勫厓绱犳斁鍦ㄥ叾闄勮繎锛岃繖涓镣癸纴鍦ˋrrays.sort()涓寰楀埌浜呜缉澶х殑浼桦寲銆
涓句緥锛15銆93銆15銆41銆6銆15銆22銆7銆15銆20
銆銆 涓句緥锛15銆93銆15銆41銆6銆15銆22銆7銆15銆20
锲爏ize澶т簬7灏忎簬绛変簬40 ,镓浠ュ湪15銆6銆佸拰20 涓阃夋嫨v = 15 浣滀负鍒掑垎鍏冦
銆銆缁忚繃涓娆℃崲鍒嗗悗锛 15銆15銆7銆6銆41銆20銆22銆93銆15銆15. 涓庡垝鍒嗗厓鐩哥瓑镄勫厓绱犻兘绉诲埌浜嗙礌缁勭殑涓よ竟銆
銆銆鎺ヤ笅𨱒ュ皢涓庡垝鍒嗗厓鐩哥瓑镄勫厓绱犵Щ鍒版暟缁勪腑闂存潵锛屽舰鎴愶细7銆6銆15銆15銆15銆15銆41銆20銆22銆93.
銆銆链钖庨掑綊瀵逛袱涓鍖洪棿杩涜屾帓搴廪7銆6]鍜孾41銆20銆22銆93].,镓浠ュ湪15銆6銆佸拰20 涓阃夋嫨v = 15 浣滀负鍒掑垎鍏冦
Ⅱ 快速排序特点
快速排序(Quicksort)是对冒泡排序的一种改进,由东尼·霍尔在1960年提出。 快速排序是指通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序。整个排序过程可以递归进行,以此达到整个数据变成有序序列。
分类
排序算法
数据结构
不定
最坏空间复杂度
根据实现的方式不同而不同
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
步骤为:
从数列中挑出一个元素,称为“基准”(pivot),
重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
在简单的伪代码中,此算法可以被表示为:
function quicksort(q)
{
var list less, pivotList, greater
if length(q) ≤ 1
return q
else
{
select a pivot value pivot from q
for each x in q except the pivot element
{
if x<pivot then add x to less
if x ≥ pivot then add x to greater
}
add pivot to pivotList
return concatenate(quicksort(less), pivotList, quicksort(greater))
}
}
原地(in-place)分区的版本
上面简单版本的缺点是,它需要的额外存储空间,也就跟归并排序一样不好。额外需要的存储器空间配置,在实际上的实现,也会极度影响速度和缓存的性能。有一个比较复杂使用原地(in-place)分区算法的版本,且在好的基准选择上,平均可以达到空间的使用复杂度。
function partition(a, left, right, pivotIndex)
{
pivotValue = a[pivotIndex]
swap(a[pivotIndex], a[right]) // 把pivot移到结尾
storeIndex = left
for i from left to right-1
{
if a[i]<= pivotValue
{
swap(a[storeIndex], a[i])
storeIndex = storeIndex + 1
}
}
swap(a[right], a[storeIndex]) // 把pivot移到它最后的地方
return storeIndex
}
这是原地分区算法,它分区了标示为"左边(left)"和"右边(right)"的序列部分,借由移动小于的所有元素到子序列的开头,留下所有大于或等于的元素接在他们后面。在这个过程它也为基准元素找寻最后摆放的位置,也就是它回传的值。它暂时地把基准元素移到子序列的结尾,而不会被前述方式影响到。由于算法只使用交换,因此最后的数列与原先的数列拥有一样的元素。要注意的是,一个元素在到达它的最后位置前,可能会被交换很多次。
一旦我们有了这个分区算法,要写快速排列本身就很容易:
procere quicksort(a, left, right)
if right>left
select a pivot value a[pivotIndex]
pivotNewIndex := partition(a, left, right, pivotIndex)
quicksort(a, left, pivotNewIndex-1)
quicksort(a, pivotNewIndex+1, right)
这个版本经常会被使用在命令式语言中,像是C语言。
快速排序
快速排序是二叉查找树(二叉搜索树)的一个空间最优化版本。不是循序地把数据项插入到一个明确的树中,而是由快速排序组织这些数据项到一个由递归调用所隐含的树中。这两个算法完全地产生相同的比较次数,但是顺序不同。对于排序算法的稳定性指标,原地分区版本的快速排序算法是不稳定的。其他变种是可以通过牺牲性能和空间来维护稳定性的。
Ⅲ 快速排序算法
快速排序是对冒泡排序算法的一种改进,同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的。
不同的是,冒泡排序在每一轮只把一个元素冒泡到数列的一端,而快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分。
快速排序是基于“分治法”原理实现,所谓分治法就是不断地将原数组序列按照一定规律进行拆分,拆分后各自实现排序直到拆分到序列只剩下一个关键字为止。
快速排序首先选取一个关键字为标志位(关键字的选取影响排序效率),然后将序列中小于标志位的关键字移动至标志位左侧,大于标志位的关键字移动至右侧。一趟比较完成后,整个序列以选取的标志位为界,左侧均小于标志位,右侧均大于关键字。
但左右两侧内部并不是有序的(左右两侧关键字个数也不一定相同)。进而继续将左右两侧分别再以这种方式进行排序,直到将序列拆分的剩余一个关键字为止,整个序列即变成有序。
Ⅳ 快速排序算法
快速排序(Quicksort)是对冒泡排序的一种改进。
然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
Ⅳ 快速排序法
快速排序(Quicksort)是对冒泡排序的一种改进。[1]
快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。[1]
中文名
快速排序算法
外文名
quick sort
别名
快速排序
提出者
C. A. R. Hoare
提出时间
1960年
快速
导航
排序步骤
程序调用举例
示例代码
性能分析
排序流程
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:[2]
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。[2]
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。[2]
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。[2]
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。[2]
排序步骤
原理
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选
快排图
用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它左边,所有比它大的数都放到它右边,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。[1]
一趟快速排序的算法是:[1]
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;[1]
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];[1]
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]的值交换;[1]
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]的值交换;[1]
5)重复第3、4步,直到i==j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。[1]
排序演示
假设一开始序列{xi}是:5,3,7,6,4,1,0,2,9,10,8。
此时,ref=5,i=1,j=11,从后往前找,第一个比5小的数是x8=2,因此序列为:2,3,7,6,4,1,0,5,9,10,8。
此时i=1,j=8,从前往后找,第一个比5大的数是x3=7,因此序列为:2,3,5,6,4,1,0,7,9,10,8。
此时,i=3,j=8,从第8位往前找,第一个比5小的数是x7=0,因此:2,3,0,6,4,1,5,7,9,10,8。
Ⅵ 如何修改快速排序算法才能使其将输入元素按非增序排序
指按降序排序。提供C语言的代码参考:
#include <stdio.h>
void out(int a[], int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
}
void quicksort(int a[], int low, int high)
{
if (low >= high) return;
int first = low;
int last = high;
int key = a[first];
while (first<last)
{
while (first<last&&a[last] <=key) --last;
a[first] = a[last];
while (first<last&&a[first] >= key) ++first;
a[last] = a[first];
}
a[first] = key;
quicksort(a, low, first - 1);
quicksort(a, first + 1, high);
}
void main()
{
int a[10]={34,3,29,63,70,16,85,82,90,93};
quicksort(a,0,10);
out(a,10);
}
(6)快速排序算法改进扩展阅读:
快速排序的基本思想是:通过一趟排序算法把所需要排序的序列的元素分割成两大块,其中,一部分的元素都要小于或等于另外一部分的序列元素,仍根据该种方法对划分后的这两块序列的元素分别再次实行快速排序算法,排序实现的整个过程可以是递归的来进行调用,最终能够实现将所需排序的无序序列元素变为一个有序的序列。
经处理后的数据便于筛选和计算,大大提高了计算效率。对于排序,我们首先要求其具有一定的稳定性,即当两个相同的元素同时出现于某个序列之中,则经过一定的排序算法之后,两者在排序前后的相对位置不发生变化。换言之,即便是两个完全相同的元素,它们在排序过程中也是各有区别的,不允许混淆不清。