快速排序是C.R.A.Hoare於1962年提出的一種劃分交換排序。它採用了一種分治的策略,一般稱其爲分治法(Divide-and-ConquerMethod)。快速排序是一種不穩定的排序法。html
temp
)temp
左右兩邊共產生了兩個子區間。因爲每一個區間內的處理方法是重複的,所以咱們能夠用遞歸函數來實現它(遞歸函數佔用棧空間),也能夠採起while循環來解決。數組
快速排序能夠輕鬆應付龐大且無序的數組,可是若用於高度有序(甚至徹底升序,降序排列好的,元素內容徹底重複的)的數組,表現反而會很糟糕。markdown
上段中提到的操做步驟2有不少種方法實現,思路大同小異。在這裏使用挖坑法來實現。 咱們首先準備:ide
low
和high
,分別指向數組的首和尾,且high
只向左移動,low
只向右移動。temp
當中。換個說法,在程序開始前,在arr[low]的位置挖了坑,該位置上的數被移到了temp中。函數
有一個大前提:在調用該函數時low < high
必須成立,不然再也不繼續遞歸。由於low
==high
意味着這個數組只有1個元素,那就沒有必須再進行排序了。oop
程序運行,low
指針不動,而high
指針判斷它所目前指向的值是否大於temp
。知足條件則左移,不然high
指針會停下來,將當前指向的值覆蓋到arr[low]
位置上。(演示圖裏第一次判斷就中了獎 =D) ui
或者說,
high
位置上的數被挖出來填到了low
位置上的坑。spa
high
指針不動,
low
指針判斷它所目前指向的值是否小於
temp
。知足條件則右移,不然
low
指針會停下來,將當前指向的值覆蓋到
arr[high]
位置上。(這一段敘述和上一段敘述互爲反過程。)
或者說,
low
位置上的數又被挖出來填了上一步high
指針位置留下來的坑。指針
high
指針再次開始左移,直到發現大於等於temp
的數,則將其挖出來填到low
指針的地方並暫停,隨後low
指針又不斷右移,直到發現小於temp
的數,再將它挖出填到high
指針處......high
和low
指針一直處於交替相向移動的狀態。code
如此下去,總有一刻high
指針和low
指針會指向同一位置。此刻無需再移動high
和low
指針,只須要把最初挖出來的temp
值,放到這個坑內便可。
咱們此時能夠發現,原先的數組已經被分爲了三部分:比temp
小的數,temp
,比temp
大(或等)的數組。
只須要再對Smaller和Greater區間進行遞歸操做,重複以前所述的步驟就能夠了。
static void quickSortJ(Integer[] arr, int start, int end) { if (start < end) { Integer low = start; Integer high = end; Integer temp = arr[low]; while (low < high) { while (high > low && arr[high] >= temp) high--; if (high > low) arr[low] = arr[high]; while (high > low && arr[low] < temp) low++; if (high > low) arr[high] = arr[low]; } arr[high] = temp; quickSortJ(arr, start, low - 1); quickSortJ(arr, high + 1, end); } } 複製代碼
咱們在進行一輪排序後(左右指針法,挖坑法,etc.)一定能將數組分割成如下形式:[Smaller[], temp, Greater[]]。那能不能用更簡單偷懶的方法來獲得Smaller區間和Greater區間呢? 在Scala中,能夠直接利用過濾器filter
來過濾出比temp
小(或大)的數。如:
arr.filter(x => x > temp) //filter處理以後獲得的還是Array[],放心食用。
然後再對過濾出來的Smaller[],和Greater[]繼續進行遞歸便可。用Java的流處理一樣能夠實現相似邏輯,可是比較麻煩。
def quickSortScl(arr: Array[Int]): Array[Int] = { if (arr.length <= 1) arr else { //這裏的temp沒有選取首元素,而是取中間元素. val temp =arr(arr.length/2) //返回一個[SmallerThanTemp[],temp,GreaterThanTemp[]]. Array.concat( quickSortScl(arr.filter(x => x<temp)), //若是有多個相等的元素,則該數組內的元素個數大於1. arr.filter(x => x==temp), quickSortScl(arr.filter(x => x>temp)) ) } } 複製代碼