看完动画你还敢说不会 快速排序
前言
由于LeetCode上的算法題很多涉及到一些基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),為了更好的理解后續(xù)更新的一些復(fù)雜題目的動畫,推出一個新系列 -----《圖解數(shù)據(jù)結(jié)構(gòu)》,主要使用動畫來描述常見的數(shù)據(jù)結(jié)構(gòu)和算法。本系列包括十大排序、堆、隊列、樹、并查集、圖等等大概幾十篇。
快速排序
快速排序是由東尼·霍爾所發(fā)展的一種排序算法。在平均狀況下,排序 n 個項目要 Ο(nlogn) 次比較。在最壞狀況下則需要 Ο(n2) 次比較,但這種狀況并不常見。事實上,快速排序通常明顯比其他 Ο(nlogn) 算法更快,因為它的內(nèi)部循環(huán)(inner loop)可以在大部分的架構(gòu)上很有效率地被實現(xiàn)出來。
快速排序使用分治法(Divide and conquer)策略來把一個串行(list)分為兩個子串行(sub-lists)。
快速排序又是一種分而治之思想在排序算法上的典型應(yīng)用。本質(zhì)上來看,快速排序應(yīng)該算是在冒泡排序基礎(chǔ)上的遞歸分治法。
算法步驟
從數(shù)列中挑出一個元素,稱為 “基準(zhǔn)”(pivot);
重新排序數(shù)列,所有元素比基準(zhǔn)值小的擺放在基準(zhǔn)前面,所有元素比基準(zhǔn)值大的擺在基準(zhǔn)的后面(相同的數(shù)可以到任一邊)。在這個分區(qū)退出之后,該基準(zhǔn)就處于數(shù)列的中間位置。這個稱為分區(qū)(partition)操作;
遞歸地(recursive)把小于基準(zhǔn)值元素的子數(shù)列和大于基準(zhǔn)值元素的子數(shù)列排序;
遞歸的最底部情形,是數(shù)列的大小是零或一,也就是永遠都已經(jīng)被排序好了。雖然一直遞歸下去,但是這個算法總會退出,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最后的位置去。
來源:github.com/hustcc/JS-S…
算法演示
排序動畫過程解釋
首先,操作數(shù)列中的所有數(shù)字
在所有數(shù)字中選擇一個數(shù)字作為排序的基準(zhǔn)(pivot), pivot 通常是隨機選擇的,在這里為了演示方便,我們選擇最右邊的數(shù)字作為 pivot
選取好 pivot 后,在操作數(shù)列中選擇最左邊的數(shù)字標(biāo)記為 左標(biāo)記 ,最右邊的數(shù)字標(biāo)記為 右標(biāo)記
將左邊的標(biāo)記向右移動
當(dāng) 左標(biāo)記 達到超過 pivot 的數(shù)字時,停止移動
在這里,8 > 6 ,所以停止移動
然后將右邊的標(biāo)記向左移動
當(dāng) 右標(biāo)記 達到小于 pivot 的數(shù)字時,停止移動
在這里,4 > 6 ,所以停止移動
當(dāng)左右標(biāo)記停止時,更改標(biāo)記的數(shù)字
因此,左標(biāo)記 的作用是找到一個大于 pivot 的數(shù)字,右標(biāo)記 的作用是找到一個小于 pivot 的數(shù)字
通過交換數(shù)字,可以在數(shù)列的左邊收集小于 pivot 的數(shù)字集合,右邊收集大于 pivot 的數(shù)字集合
交換之后,繼續(xù)移動 左標(biāo)記
在這里,9 > 6 ,所以停止移動
然后將右邊的標(biāo)記向左移動
當(dāng) 右標(biāo)記 碰撞到 左標(biāo)記 時也停止移動
如果左右側(cè)的標(biāo)記停止時,并且都在同一個位置,將這個數(shù)字和 pivot 的數(shù)字交換
這就完成了第一次操作
小于 6 的都在 6 的左側(cè),大于 6 的都在 6 的右側(cè)
然后遞歸對這分成的兩部分都執(zhí)行同樣的操作
完成 快速排序
代碼實現(xiàn)
為了更好的讓讀者用自己熟悉的編程語言來理解動畫,筆者將貼出多種編程語言的參考代碼,代碼全部來源于網(wǎng)上。
C++代碼實現(xiàn)
Java代碼實現(xiàn)
Python代碼實現(xiàn)
JavaScript代碼實現(xiàn)
如果你是iOS開發(fā)者,可以在GitHub上 github.com/MisterBooo/… 獲取更直觀可調(diào)試運行的源碼。
歡迎關(guān)注:
總結(jié)
以上是生活随笔為你收集整理的看完动画你还敢说不会 快速排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你缺啥,你缺一个得力的办公软件
- 下一篇: (Ajax)axios源码简析(三)——