介紹一下快速排序方法,不能老是用冒泡排序方法。另外一些編程語言也有自己的排序方法,例如:AS有sort,在Array中有。但是我順便說一句:在AS3中,不要輕易使用遞歸算法,你可以自己做一個Test,當你從1+2+3......一直加到50幾的時候(用遞歸算法),那麼程序就會被卡死,在AS3中遞歸是可行的,但是次數一定不能過多。我之所以把這篇文章寫在C#當中,因爲快速算法要用到遞歸。這裏多說一句,在AS3中不要用快速排序,因爲你很難保證,你的集合的元素數量沒有超過AS3遞歸的界限,那麼,在Array中用Sort,在Vector中,我在以前寫的“關於AS3中Vector的sort排序”中有,讀者可以看看。
首先 : 來說說思想
對比與冒泡排序的整體排序,快速排序方法用的是分支排序。
首先,他有一個基準點(pivot),把pivot的左邊的和右邊的元素進行整理(當降序排列時,pivot左邊的元素>=pivot,右邊的元素<=povit,反之亦然),然後再次選擇pivot進行排序(遞歸)
void QuickAscSort( ref vector<int> v, int left, int right){ if(left < right){ int key = v[left]; int low = left; int high = right; while(low < high){ while(low < high && v[high] > key){ high-=1; } if(low < high) v[low++] = v[high]; while(low < high && v[low] < key){ low+=1; } if(low < high) v[high--] = v[low]; } v[low] = key; QuickAscSort(v,left,low-1); QuickAscSort(v,low+1,right); } }
上面的是一個升序的排列方式
下面是一個降序的方法
void QuickDesSort( ref vector<int> v, int left, int right){ if(left < right){ int key = v[left]; int low = left; int high = right; while(low < high){ while(low < high && v[high] < key){ high-=1; } if(low < high) v[low++] = v[high]; while(low < high && v[low] > key){ low+=1; } if(low < high) v[high--] = v[low]; } v[low] = key; QuickDesSort(v,left,low-1); QuickDesSort(v,low+1,right); } }
例如 : [2,5,7,8,9,10,4,6,8,2,3,11,27,12,14,15] a 的排序
QuickAscSort( ref a , 0,a.lenght - 1 ); 這是一個升序的排列方式 , 反之亦然。
另外加一個綜合的方法 :
void QuickSort( ref vector<int> v, int left, int right , bool isAsc ){ if(left < right){ int key = v[left]; int low = left; int high = right; while(low < high){ if( !isAsc ){ while(low < high && v[high] < key){ high-=1; } if(low < high) v[low++] = v[high]; while(low < high && v[low] > key){ low+=1; } if(low < high) v[high--] = v[low]; }else{ while(low < high && v[high] > key){ high-=1; } if(low < high) v[low++] = v[high]; while(low < high && v[low] < key){ low+=1; } if(low < high) v[high--] = v[low]; } } v[low] = key; QuickDesSort(v,left,low-1 , isAsc); QuickDesSort(v,low+1,right , isAsc); } }
盡情的用吧 : 升序 QuickSort(ref a , 0 , a.lenght- 1 , true );
降序 QuickSort(ref a , 0 , a.lenght- 1 , false );
無法應對 array中有相同值的排序 ----
二,以上方案鬥不足以對有多個相同的值的Array進行排序 (會造成混亂)
新的商業方案:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace mY { class Program { public void QuickSortFunction(int[] array, int low, int high) { try { int keyValuePosition; //記錄關鍵值的下標 //當傳遞的目標數組含有兩個以上的元素時,進行遞歸調用。(即:當傳遞的目標數組只含有一個元素時,此趟排序結束) if (low < high) { keyValuePosition = keyValuePositionFunction(array, low, high); //獲取關鍵值的下標(快排的核心) QuickSortFunction(array, low, keyValuePosition - 1); //遞歸調用,快排劃分出來的左區間 QuickSortFunction(array, keyValuePosition + 1, high); //遞歸調用,快排劃分出來的右區間 } } catch (Exception ex) { } } //快速排序的核心部分:確定關鍵值在數組中的位置,以此將數組劃分成左右兩區間,關鍵值遊離在外。(返回關鍵值應在數組中的下標) private int keyValuePositionFunction(int[] array, int low, int high) { int leftIndex = low; //記錄目標數組的起始位置(後續動態的左側下標) int rightIndex = high; //記錄目標數組的結束位置(後續動態的右側下標) int keyValue = array[low]; //數組的第一個元素作爲關鍵值 int temp; //當 (左側動態下標 == 右側動態下標) 時跳出循環 while (leftIndex < rightIndex) { while (leftIndex < rightIndex && array[leftIndex] <= keyValue) //左側動態下標逐漸增加,直至找到大於keyValue的下標 { leftIndex++; } while (leftIndex < rightIndex && array[rightIndex] > keyValue) //右側動態下標逐漸減小,直至找到小於或等於keyValue的下標 { rightIndex--; } if (leftIndex < rightIndex) //如果leftIndex < rightIndex,則交換左右動態下標所指定的值;當leftIndex==rightIndex時,跳出整個循環 { temp = array[leftIndex]; array[leftIndex] = array[rightIndex]; array[rightIndex] = temp; } } //當左右兩個動態下標相等時(即:左右下標指向同一個位置),此時便可以確定keyValue的準確位置 temp = keyValue; if (temp < array[rightIndex]) //當keyValue < 左右下標同時指向的值,將keyValue與rightIndex - 1指向的值交換,並返回rightIndex - 1 { array[low] = array[rightIndex - 1]; array[rightIndex - 1] = temp; return rightIndex - 1; } else //當keyValue >= 左右下標同時指向的值,將keyValue與rightIndex指向的值交換,並返回rightIndex { array[low] = array[rightIndex]; array[rightIndex] = temp; return rightIndex; } } static void Main(string[] args) { Program pro = new Program(); int[] c = new int[] { 1,7,3,5,9,8,2,7,7,8,1,3}; pro.QuickSortFunction( c, 0, c.Length - 1); Console.WriteLine("~~~~~~~~~~~"); for (int i = 0; i < c.Length; i++) { Console.WriteLine(c[i]); } Console.ReadKey(); } }
結果:
妥妥的沒毛病...........