超快排怎么回事-什么是关键向导快速排序(比冒泡更快更有效的算法)?
发布时间:2021-07-27
冒泡排序是O(N^2),实际上在排序过程中效率很低。在扫荡拍卖或其他需要比拼速度的时候,时间就是金钱~越快抓住机会。 今天我们介绍另一种更快更高效的排

什么是关键向导快速排序(比冒泡更快更有效的算法)?

冒泡排序是O(N^2),实际上在排序过程中效率很低。在扫荡拍卖或其他需要比拼速度的时候,时间就是金钱~越快抓住机会。

今天我们介绍另一种更快更高效的排序——快速排序,时间复杂度为 O(n*logn)。

快速排序算法思想

快速排序使用分而治之的策略,通常称为分治法。

该方法的基本思想是:

1、首先从编号序列中取一个数字作为参考编号。 (不要被这个术语吓到,它是一个参考数字,以后你会知道它是做什么用的)。

2、在分区过程中,所有大于这个数的数放在右边,所有小于等于它的数放在左边。

3、对左右区间重复第二步,直到每个区间只有一个数字。

算法的白话解释:

假设我们现在对 10 个数字“08”进行排序。让第一个数字 6 为基数。接下来,需要将这个序列中所有大于参考号的数字放在6的右边,小于参考号的数字放在6的左边。

方法其实很简单:开始从初始序列“08”的两端“探测”。先从右到左找一个小于6的数,再从左到右找一个大于6的数,然后交换。这里可以使用两个变量 i 和 j,分别指向序列的最左边和最右边。我们给这两个变量命名为“Sentinel i”和“Sentinel j”。一开始,让哨兵i指向序列的最左边(即i=1)并指向数字6、让哨兵j指向序列的最右边(即=10)并指向数字.

-8-:45 上传

下载附件(9、)

第一个哨兵j开始派遣。因为这里设置的基准数是最左边的数,所以让哨兵j先调度很重要(请思考为什么)。 Sentinel j 一步步向左移动(即 j--),直到找到一个小于 6 的数字并停止。接下来,哨兵 i 一步一步向右移动(i++),直到找到一个大于 6 的数字并停止。最后哨兵j停在了5号前面,哨兵i停在了7号前面。

-8-:45上传

下载附件(9、)

-8-:45上传
下载附件(8、)

现在交换哨兵i和哨兵j指向的元素值。交换后的顺序如下:

-8-:45 上传

下载附件(9、)

-8-:45 上传

下载附件(8、)

to 所以,第一次交流就结束了。接下来启动哨兵j,继续向左移动(然后友情提示,每次哨兵j都要先启动)。他找到了 4 个(小于基准数 6 并且满足要求)然后停止。哨兵我也继续向右移动。他找到了 9(大于基准数 6、满足要求)然后停止。此时再次进行交换,交换后的顺序如下:

第二次交换结束,继续“探测”。哨兵j继续向左移动。他找到了 3(小于基准数 6 并满足要求)然后停止。哨兵 i 继续向右移动,这很糟糕!这时,哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到了3的前面。这意味着“探查”到此结束。我们交换基准号6和3、交换后的顺序如下:

-8-:45上传

下载附件(8、)

-8-:45上传

下载附件(10、)

- 8-:45 上传

下载附件(8、)

超快排怎么回事:pascal快排,为什么超时??

超快排怎么回事:pascal快排,为什么超时??

到此,第一轮“检测”真的结束了。此时以参考数字6为分界点,6左边的数字均小于等于6、6右边的数字大于等于6、刚才的过程,其实哨兵j的任务就是找一个小于参考号的数字,哨兵i的任务就是找一个大于参考号的数字,直到i和j相遇。

好的,讲解完毕。现在基准数字 6 又回到了它的位置,它恰好在序列中的第 6 个位置。至此,我们已经将原始序列以6为分割点分成了两个序列。左边的序列是“”,右边的序列是“”。接下来需要分别处理这两个序列。因为6左右的顺序还是很混乱的。不过没关系,我们已经掌握了方法,接下来就模拟刚才的方法,分别处理6左右的序列。现在让我们先处理 6 左边的序列。

左边的顺序是“”。请以3为基数调整这个序列,使3左边的数字小于等于3、右边的数字大于等于3、 2 第一次交换后:以3为分界点将两个序列分开。左边小于3、右边大于3、 3 然后分别处理3左右的两个序列“21”和“54”。 3 这样,我们就已经处理完我们最初划分的6左边的序列了~~我们以9为基数来处理6和10右边的序列吧。 , 第一次交换完成:8 第二次交换:9 再次交换:9 这样,我们的整个序列就排序好了。快速排序算法代码实现:

su="6、1、2、7、9、 3、4、5、10、8"

su=Split(su,"|")

L= UBound(su)

Callks(0,L)

Functionks(L,B)

IfL>Bthen超快排怎么回事

ExitFunction

EndIf//判断数组的上标和下标是否出range

key=int(su(L))//提取数组的第一位作为基数

Whilej>i

Whileint(su(j))>= keyandj>i//我们必须从右边开始,找到小于key的第一个数字。这里加j>i的判断是为了防止j的值不断减小,导致下标越界

j=j-1

Wend

Whileint(su(i))<= keyandj>i//从左边开始寻找第一个大于key的数字(这里的字符串数组需要转成数值)

i=i+1

Wend

Ifj> iten//与base key比较得到的两个数的交换将大于key的值往右边放小于key的值往左边

T=su(i)

su(i )=su(j)

su(j)=T

EndIf

Wend//当i=j第一轮比较完成时这个While循环退出

su(L)=su( i)//将数组的第一个元素重置为基数

su(i)=key//返回基数Position(回合完成后,左边的数字<基数><右边的数字,那么基数就是它应该在排序的位置。)>

Callks(L,i-1)//继续处理左边的数字

Callks(i+1,B)//继续处理处理 r 上的数字ight

EndFunction

Fori=0ToUBound(su)

TracePrintsu(i)

Next

什么是关键向导快速排序(比冒泡更快更有效的算法)?

XFM99_
XFM99_
已为您复制好微信号,点击进入微信
QQ在线咨询
在线咨询
18176216589
在线客服
18176216589
XFM99_
XFM99_
已为您复制好微信号,点击进入微信