從別人博客上找到一篇關於as3快速排序的代碼,使用後發現在有大量相同數據的情況下,排序不可靠,容易出現堆棧溢出的現象,
記起看過一個C的二叉樹排序法,現改成AS3版本並加以註釋。
全部代碼如下
private function mysort(array:Vector.<int>,left:int,right:int):void{
var tl:int = left;var tr:int = right;
var center:int = array[tl];
while(tl<tr){
while(array[tl] < center) tl++;
while(array[tr] > center) tr--;
if(tl>=tr)break;
var temp:int = array[tl];
array[tl] = array[tr];
array[tr] = temp;
if(array[tl] == center)tr--;
if(array[tr] == center)tl++;
}
f(tl == tr){
tl++;tr--;
}
if(tl < right)mysort(array,tl,right);
if(tr > left)mysort(array,left,tr);
}
首先定義一個本輪的左遊標和右遊標 tl tr
然後隨機取一個成員作爲中間值
var center:int = array[tl];
你可以選取任何一個成員 當然也可以選擇中間的成員 這個中間值與每個成員無關 但必須等於其中一個成員
array[int((tl+tr)/2)];
先左遊標開始向右查找大於等於中間值的成員,沒找到則移動遊標直到找到爲止。同理 右遊標向左查找小於中間值的成員
while(array[tl] < center) tl++;
while(array[tr] > center) tr--;
由於我們選取的中間值是待排序數組的一個成員,所以即便數據排列已經是期望結果,我們依然能夠拿到一組指向中間值的數據。
當左右遊標都找到目標後,進行交換,假如左右遊標指向的數據正好等於中間值,則將遊標移動到下一位,但是我們已經交換過數據,此時的左遊標指向的其實是交換前右遊標指向的數據。
if(array[tl] == center)tr--;
if(array[tr] == center)tl++;
當數據按我們的要求排列好後,由於左遊標要大於右遊標,而它們中間的必定即大於等於中間值也小於等於中間值,即等於中間值。不必再參與排序。
所以此時左遊標之後的數據都是大於等於中間值的,而右遊標之前的數據都是小於等於中間值。我們將它們繼續遞歸,最後得到結果。