快速排序算法图解分析
文章目錄
- 一、快速排序介紹
- 二、圖解
- 三、代碼分析
- 3.1交換函數
- (1)一直交換
- (2)左右交換
- (3)填數
- (4)三種方法簡析
- 3.2遞歸實現快排
- 四、完整代碼
一、快速排序介紹
1.快速排序是對冒泡排序的改進。冒泡排序每次交換只能使原序列的逆序數減一(相鄰元素的交換),而快速排序可以進行不相鄰元素的交換,逆序數至少減少1。(當排序序列逆序數為0時,排序就完成了)
- 百度百科的逆序數解釋:
2.基本思想(以升序排序為例):
二、圖解
下圖中只用看思想,排序過程中實際數的順序不一定是這樣的。這里選每個數組中第一個數當參照數,實際參照數可以有多種選擇方案。
三、代碼分析
3.1交換函數
快排中最重要就是將比參照數小的放在其左邊,大的放在其右邊的方法。這里我看了一些文章,結合自己的思考,總結了三個方法。
(1)一直交換
這里定義兩個指針分別指向數組的頭與尾。
a. 判斷尾指針所在元素是否小于參照數(即頭指針指向的數),不小于,尾指針就一直向左移,直到找到小于參照數的數或到達頭指針(兩指針相遇,循環就結束),將頭尾指針元素交換。
b.接著判斷頭指針所在元素是否大于參照數(即尾指針指向的數),不大于,頭指針就一直向右移,直到找到大于參照數的數或到達尾指針(兩指針相遇,循環就結束),將頭尾指針元素交換。
c.反復進行步驟ab,直到頭尾指針相遇。
**思考:**這樣可以保證頭指針前的都是小于參照數的,尾指針后的都是大于參照數的。
圖解:
這里以arr={5, 4, 8, 2, 7, 1}為例
尾指針小于5,交換。(一定要尾指針先判斷,因為頭指針記錄著參照數。)
頭指針開始判斷:
找到,交換。
尾指針開始判斷。
找到,交換。
頭指針開始判斷。
兩指針相遇,結束。
代碼:
(2)左右交換
定義兩個指針分別指向數組的頭與尾。
a. 判斷尾指針所在元素是否小于參照數(即頭指針指向的數),不小于,尾指針就一直向左移,直到找到小于參照數的數或到達頭指針(兩指針相遇,循環就結束),這里先不進行交換。
b.接著判斷頭指針所在元素是否大于參照數(即尾指針指向的數),不大于,頭指針就一直向右移,直到找到大于參照數的數或到達尾指針(兩指針相遇,循環就結束),這時進行交換。
c.反復進行步驟ab,直到頭尾指針相遇,將該處元素與參照數互換。
圖解:
這里還以arr={5, 4, 8, 2, 7, 1}為例
右邊判斷找到,左邊開始判斷。
兩邊都找到,交換。
右邊開始找。
找到,左邊開始找。
兩指針相遇,此處元素與參照數互換。(這里可以看出一定要右邊指針先判斷,否則兩指針相遇時所指向的元素大于參照數)
完成。
代碼:
public static int change2(int[] arr, int left, int right){int l = left;//頭指針int r = right;//尾指針while(l < r){while(arr[r] >= arr[left] && l < r){//尾指針判斷r--;}while(arr[l] <= arr[left] && l < r){//頭指針判斷l++;}int temp = arr[r];//交換arr[r] = arr[l];arr[l] = temp;}int temp = arr[left];//與操作數的交換arr[left] = arr[l];arr[l] = temp;return l;}(3)填數
定義兩個指針分別指向數組的頭與尾。用臨時變量將參照數存儲起來。
a. 判斷尾指針所在元素是否小于參照數(即頭指針指向的數),不小于,尾指針就一直向左移,直到找到小于參照數的數或到達頭指針(兩指針相遇,循環就結束),用尾指針的元素將頭指針的元素覆蓋。
b.接著判斷頭指針所在元素是否大于參照數(即尾指針指向的數),不大于,頭指針就一直向右移,直到找到大于參照數的數或到達尾指針(兩指針相遇,循環就結束),用頭指針的元素將尾指針的元素覆蓋。
c.反復進行步驟ab,直到頭尾指針相遇,用參照數將該處元素覆蓋。
圖解:
這里還以arr={5, 4, 8, 2, 7, 1}為例
將參照數存儲,右邊先動,找到,覆蓋。
左邊開始找。
找到,覆蓋。
右邊開始找。
找到,覆蓋。
左邊開始找。
兩指針相遇,操作數進行覆蓋。
完成。
代碼:
public static int change3(int[] arr, int left, int right){int l =left;//左指針int r = right;//右指針int temp = arr[left];//存儲參照數while(l < r){while(temp <= arr[r] && l < r){//左邊找r--;}arr[l] = arr[r];//覆蓋while(temp >= arr[l] && l < r){//右邊找l++;}arr[r] = arr[l];//覆蓋}arr[r] = temp;//覆蓋return r;}(4)三種方法簡析
看代碼量與實際操作數量,第三種效果最好,第一種最差。
3.2遞歸實現快排
代碼:
public static void quickSort(int[] arr, int left, int right){if(right <= left){return;}int r = change3(arr,left,right);quickSort(arr,left,r-1);quickSort(arr,r+1,right);}四、完整代碼
public class QuickSort {public static void main(String[] args) {int arr[] = {4,5,65,20,855,87,12,8,0,6,54,879,32,45,321,65,58,654,23,8,15};quickSort(arr,0,arr.length-1);System.out.println(Arrays.toString(arr));}public static void quickSort(int[] arr, int left, int right){if(right <= left){return;}int r = change3(arr,left,right);quickSort(arr,left,r-1);quickSort(arr,r+1,right);}public static int change3(int[] arr, int left, int right){int l =left;//左指針int r = right;//右指針int temp = arr[left];//存儲參照數while(l < r){while(temp <= arr[r] && l < r){r--;}arr[l] = arr[r];while(temp >= arr[l] && l < r){l++;}arr[r] = arr[l];}arr[r] = temp;return r;} }總結
以上是生活随笔為你收集整理的快速排序算法图解分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 霍夫曼树(最优二叉树)的实现
- 下一篇: 希尔排序算法图解分析