大话数据结构系列之快速排序算法
大話數據結構系列之快速排序算法
文章目錄
- 實現思路
- 重點知識
- 代碼實現
- 優化策略
- 算法比較
- 與各位共勉
實現思路
1、屬于冒泡排序的升級版,都是通過不斷的比較和移動交換來實現排序,它的實現,增大了記錄的比較和移動的距離,將關鍵字較大的記錄從前面直接移動到后面,關鍵字較小的記錄從后面直接移動到前面,從而減少了總的比較次數和移動交換次數。
2、通過一趟排序將待記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的。
重點知識
樞軸:
樞軸左邊的值都比它小,右邊的值都比它大
Partition 函數(用來尋找樞軸,進行表劃分):
其實就是將選取的 pivotkey 不斷交換,將比它小的換到它的左邊,比它大的換到它的右邊,它也在交換中不斷更改自己的位置,直到完全滿足這個要求為止。
如果每次 pivotkey 選擇的值都最優,那么遞歸的深度就越淺,那么時間性能就越好
復雜度分析:
空間復雜度為O[nlogn]——O[n]
時間復雜度為 O[nlogn] —— O[n2]
快速排序法的時間復雜度推導過程:
使用數學歸納法進行推導:https://blog.csdn.net/weixin_39966065/article/details/104157850
代碼實現
package com.example.sort; import java.util.Arrays; public class QuickSortTest {public static void main(String[] args){//基礎數據int[] sortList2 = {0,1,4,3,10,9,6,7,8,5,2,20,18,16,11,13,15,14,17,19,12};System.out.println(Arrays.toString(sortList2));quickSort(sortList2);System.out.println(Arrays.toString(sortList2));}public static void quickSort(int[] list){qSort(list,0,list.length-1);}public static void qSort(int[] list, int low, int high){int pivot;if(low < high){pivot = partition(list,low,high);//分別對高低子表進行排序qSort(list,low,pivot-1);qSort(list,pivot+1,high);}}//采用尾遞歸:將遞歸轉換為迭代問題public static void qSort2(int[] list, int low, int high){int pivot;while(low < high){pivot = partition(list,low,high);//分別對高低子表進行排序qSort2(list,low,pivot-1);low = pivot + 1;}}public static int partition(int[] list, int low, int high){int pivotkey;pivotkey = list[low];while(low < high){while( low < high && list[high] >= pivotkey)high--;swap(list,low,high);while( low < high && list[low] <= pivotkey)low++;swap(list,low,high);}return low;}public static int partition1(int[] list, int low, int high){int pivotkey;//優化獲取樞軸 //1//三數取中法:至多增加了3次比較和3次交換指令,而實現了樞軸選取的合理性int m = low + (high - low)/2;if(list[low] > list[high])swap(list,low,high);if(list[m] > list[high])swap(list,high,m);if(list[m] > list[low])swap(list,m,low);pivotkey = list[low];//優化不必要的交換操作 //2//將樞軸值備份到 0 的位置list[0] = pivotkey;while(low < high){while( low < high && list[high] >= pivotkey)high--;list[low] = list[high];//swap(list,low,high);while( low < high && list[low] <= pivotkey)low++;list[high] = list[low];//swap(list,low,high);}list[low] = list[0];return low;}public static void swap(int[] list, int i, int j){int temp = list[i];list[i] = list[j];list[j] = temp;} }優化策略
1、優化選取樞軸
// 默認代碼中: pivotkey = list[low]; 并不適用于所有的情景(當所有值都倒序或者正序時,獲取的值沒有太大意義)
隨機選擇樞抽的方式更適用于大多數情況,使得獲取的樞軸更合理
三數取中法(median-of-three)
取三個關鍵字先進行排序,將中間數作為樞軸,一般是取左端、右端和中間三個數。
2、優化不必要的交換
3、優化小數組時的排序方案
當 high - low 不大于某個常數時,就可以直接用插入排序(在小數組排序中,性能最好),這樣就能保證最大化地利用兩種排序的優勢來完成工作。
4、使用尾遞歸方式減少遞歸層數
算法比較
1、從最好情況看:
如果你的待排序序列總是基本有序,冒泡排序和直接插入排序更勝一籌。時間復雜度都接近 O[n]
2、從最壞情況看:
堆排序和歸并排序強過快速排序以及其它簡單排序。
3、從平均情況,最好情況,最壞情況,空間復雜度,穩定性來比較
4、從移動次數來比較三種簡單排序
結論 :如果記錄的關鍵字本身信息量比較大(例如:關鍵字都是數十位的數字),此時表明其占用存儲空間很大,這樣移動記錄所花費的時間也越多。
5、為什么綜合各項指標來說,經過優化的快速排序是性能最好的排序算法?
(1)從最壞情況來看,歸并排序比快速排序好
(2)從最好情況看,兩者相當 ?
快速排序:
最好:nlogn | 最壞:n(n-1)/2
(3)從穩定性看,歸并排序具有穩定性
(4)從輔助空間上看,歸并排序比快速排序略次(空間一般都不是問題)
(5)從內存占用上看,無遞歸的歸并排序比快速排序有優勢
待自我論證,使用合適的數據規模
參考文章:https://blog.csdn.net/qq_36770641/article/details/82669788
與各位共勉
數據結構和算法對于程序員的人生來說,那就是兩個圓圈的交集部分,用心去掌握它,你的編程之路將會是坦途。
—— 程杰
You got a dream, you gotta protect it. People can’t do something themselves, they wanna tell you can’t do it. If you want something, go get it, Period.
《當幸福來敲門》
總結
以上是生活随笔為你收集整理的大话数据结构系列之快速排序算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐C语言编译器(手机APP)
- 下一篇: 机械设计基础类毕业论文文献都有哪些?