java資料結構之快速排序
排序演算法是java資料結構的基礎,也是程式設計師必備的基礎演算法之一,個人認為,瞭解並掌握排序演算法的思想比起單純用程式碼實現功能更有意義,畢竟創造這套演算法的思想才是最高的智慧嘛,下面就來說說關於排序演算法中的比較經典的演算法——快速排序;
先用幾張示意圖來說說快速排序的思想,
1、首先給定一個無序的陣列,定義兩個指標i和j,他們的起始位置分別是左邊的最小下標和右邊的最大下標,同時為方便起見,這裡使用陣列的第一個數作為基準值,這個基準值就是整個快速排序過程中第一輪迴圈需要使用的值,
2、首先移動j的值,從最右邊開始查詢,找到第一個比66小的值,即找到第一個小於基準值的值,然後取出來,填補到66所在的第一個位置,即i=0處,
找了第一個比66小的值42,取出來,填充到1=0處,然後,再移動左指標,從左往右找,找到第一個比66大的值,88,填補j=5的位置,
然後,再從右邊向左邊找,移動j,每次j–,找到比66小的位置,再從左往右找,重複上面的過程,直到i=j兩個位置重合,此時的意思是i=j的位置上,左邊的數都比66小,右邊的都比66大,第一輪迴圈查詢結束,同時將66填充到i=j=4的位置上;
接下來,將以i=j=66的位置為分界線,分成左右兩個新的陣列,左右兩邊的陣列同樣適用上述的方式進行查詢排序,由此,我們是不是可以想到適用什麼比較適合呢?沒錯,就是遞迴,接下去就是遞迴不斷重複排序的過程,最終可以得到排序後的陣列;
下面用具體的程式碼來實現排序的功能,具體的解釋可參考註釋,
public class FastSortOrderMath { public static void main(String[] args) { //1、給定一個無序陣列 int[] arr = {66,13,58,88,59,42,83,74,48,95}; //2、輸出無序陣列 System.out.println(Arrays.toString(arr)); //3、快速排序 quickSort(arr); //4、輸出排序後的有序陣列 System.out.println(Arrays.toString(arr)); } public static void quickSort(int[] arr) { int low = 0; int high = arr.length - 1; quickSort(arr,low,high); } private static void quickSort(int[] arr, int low, int high) { if(low < high){ //分割槽,將一個數組分成兩個陣列,找到分割槽界限的值的索引並返回 int index = partition(arr,low,high); //對左邊的分割槽進行快排 quickSort(arr,low,index-1); //再對右邊的分割槽進行快排序 quickSort(arr,index+1,high); } } //分割槽方法 private static int partition(int[] arr, int low, int high) { //指定兩個指標i , j int i = low; int j = high; //將第一個數作為基準值,挖坑 int x = arr[low]; //使用迴圈進行分割槽操作 while(i<j){ //1、從右向左移動,找到第一個小於基準值的值,arr[j] while(arr[j] >= x && i<j){ j--; } //2、將右側找到的小於基準值的值取出來填充到左邊的 i的位置即坑的位置,然後i++,左指標向中間移動位置 if(j > i){ arr[i]=arr[j]; i++; } //3、再從左側i的位置開始移動,找到第一個大於基準值的位置arr[i] while(arr[i] < x && i<j){ i++; } //4、將左側找到的大於等於基準值的值加入到右側的坑中,然後右指標向左邊移動一個位置,j-- if(i<j){ arr[j] = arr[i]; j--; } } //使用基準值填坑,這個就是基準值的最後的位置 arr[i]=x; //返回基準值所在的索引位置 return i; }
執行一下,看到控制檯的列印結果,
總結來說,快速排序 = 冒泡+分割槽治理+遞迴,整個過程用一句通俗的話來說,就是東拆西補或西拆東補,一邊拆,一邊補,這樣的思想是不是很有意思。
以上演示了快速排序的過程,由於個人經驗有限,如有理解上的偏差,請多多包涵,示意圖的細節沒有全部新增,主要是幫助理解排序過程,謝謝觀看!