1. 程式人生 > >排序算法(快速排序)

排序算法(快速排序)

元素 urn i++ 有序 width gif 位置 span height

  快排其實很簡單,理解我個人覺得沒有問題,可是代碼實現就有點無力,淚奔

快排圖解

技術分享圖片

  其實我覺得這個圖在不理解的人眼裏明不是很生動形象,我來解釋一下:找一個參照數(第一個或者最後一個都無所謂),然後先從右邊開始掃描,找到比這個數小的,再從左邊開始掃描,找到比這個數大的,兩個交換,最後的結果是,左邊的數全部比基數大,右邊的數全部比基數小;左邊右邊重復這個操作最後就有序了

  既然每一次都要將一段數組劃分成2段,中間操作一樣,我們就可以使用遞歸來實現,如果不會遞歸就自己去掌握了

遞歸實現

 1 //快排的遞歸調用
 2     public void QuickSort(int[] nums, int
left, int right){ 3 //這裏是出口條件 4 if(left > right) return; 5 6 int i = left; //左邊 7 int j = right; //右邊 8 int x = nums[left]; //基準數 9 10 while(i < j){ 11 //從右開始尋找比基準數小的元素 12 while(i < j && nums[j] > x){
13 j--; 14 } 15 //從左開始找比基準數大的元素 16 while(i < j && nums[i] <= x){ 17 i++; 18 } 19 //交換 20 if(i < j){ 21 int p = nums[i]; 22 nums[i] = nums[j];
23 nums[j] = p; 24 } 25 } 26 //基數歸位(這裏的nums[left]不能寫成x,因為這是數組裏面的數據進行交換,用x的話裏面有個元素根本沒動) 27 int temp = nums[i]; 28 nums[i] = nums[left]; 29 nums[left] = temp; 30 //排左邊 31 QuickSort(nums, left, i-1); 32 //排右邊 33 QuickSort(nums, i+1, right); 34 }

非遞歸的實現

  我們在每一次的遞歸中都用到了兩個元素,左邊位置和右邊位置,現在我們可以用棧來模擬,棧裏面的元素可以看成一對一對的(一左一右),每一次把數組劃分成2份的左右位置都按次序壓棧,到最後棧頂的兩個元素可以理解成最小兩個需要排序的位置,排好了就出棧

排序算法(快速排序)