1. 程式人生 > >對比一下陣列排序演算法效率

對比一下陣列排序演算法效率

package
{
        import flash.display.Sprite;
        import flash.utils.getTimer;

        /**
         * 測試排序效率
         * @author pelephone
         */       
        public class SortTest extends Sprite
        {
                public function SortTest()
                {
                        var arr:Array = new Array(),i:int,j:int,t:Object,gt:Number;
                        for(i=0;i<9999;i++){
                                arr.push(int(Math.random()*9999));
                        }
                       
                        gt = getTimer();
//                        quickSort(arr,0,9999);
//                        arr.sort();
//                        bubbleSort(arr);
//                        cocktailSortArr(arr);
//                        insertionSortArr(arr);
                        trace("演算法用時:",(getTimer()-gt),"毫秒");
                }
               
                /**
                 * 普通的氣泡排序
                 * @param arr
                 */
                private function bubbleSort(arr:Array):void
                {
                        var len:int = arr.length;
                        for (var i:int = 0; i < len; i++)
                        {
                                for (var j:int = i + 1; j < len; j++)
                                {
                                        if (arr[i] < arr[j])
                                        {
                                                var t:* = arr[i];
                                                arr[i] = arr[j];
                                                arr[j] = t;
                                        }
                                }
                        }
                }
               
                /**
                 * 氣泡排序優化
                 * @param arr
                 */
                private function bubblesSortPlus(arr:Array):void
                {
                        var end:int = arr.length -1;
                        while (end > 0)
                        {
                                var k:int = 0;
                                for (var i:int = 0; i < end; i++)
                                {
                                        if (arr[i] < arr[i + 1])
                                        {
                                                var t:* = arr[i];
                                                arr[i] = arr[i + 1];
                                                arr[i + 1] = t;
                                                k = i;
                                        }
                                }
                                end = k;
                        }
                }
               
                /**
                 * 插入排序
                 * @param arr
                 */
                private function insertionSortArr(arr:Array):void
                {
                        var i:int = 1;
                        var n:int = arr.length;
                       
                        for(i=1;i<n;i++) {
                                var temp:Number = arr[i];
                                var j:int = i - 1;
                               
                                while((j>=0) && (arr[j] > temp)) {
                                        arr[j+1] = arr[j]; 
                                        j--;
                                }
                               
                                arr[j+1] = temp;
                        }
                }
               
                /**
                快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分為兩個子序列(sub-lists)。 
               
                步驟為: 
               
                1. 從數列中挑出一個元素,稱為 "基準"(pivot), 
                2. 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割之後,該基準是它的最後位置。這個稱為分割(partition)操作。 
                3. 遞迴地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。 
               
                遞迴的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞迴下去,但是這個演演算法總會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。 
                */                
                private function quickSort(arr:Array,low:int,high:int):void {
                        var i:int;
                        var j:int;
                        var x:int;
                       
                        if (low < high) { //這個條件用來結束遞迴
                               
                                i = low;
                                j = high;
                                x = arr[i];
                               
                                while (i < j) {
                                        while (i < j && arr[j] > x) {
                                                j--; //從右向左找第一個小於x的數
                                        }
                                        if (i < j) {
                                                arr[i] = arr[j];
                                                i++;
                                        }
                                       
                                        while (i < j && arr[i] < x) {
                                                i++; //從左向右找第一個大於x的數
                                        }
                                       
                                        if (i < j) {
                                                arr[j] = arr[i];
                                                j--;
                                        }
                                }
                               
                                arr[i] = x;
                                quickSort(arr, low, i - 1);
                                quickSort(arr, i + 1, high);
                        }
                }
                /** 
                選擇排序是這樣實現的: 
                1.首先在未排序序列中找到最小元素,存放到排序序列的起始位置 
                2.然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到排序序列末尾。 
                3.以此類推,直到所有元素均排序完畢。 
                */ 
                public function selectionSort(result:Array):Array {
                        var i:int = 0;
                        var j:int = 0;
                        var n:int = result.length;
                       
                        for (i = 0; i < n - 1; i++) {
                                var min:int = i;
                                for (j = i+1; j < n; j++) {
                                        if (result[j] < result[min]) {
                                                min = j;
                                        }
                                }
                                /* swap data[i] and data[min] */ 
                                var temp:Number = result[i];
                                result[i] = result[min];
                                result[min] = temp;
                        }
                       
                        return result;
                } 
               
                /**
                雞尾酒排序,也就是定向氣泡排序, 雞尾酒攪拌排序, 攪拌排序 (也可以視作選擇排序的一種變形), 漣漪排序, 來回排序 or 快樂小時排序,
                是氣泡排序的一種變形。此演算法與氣泡排序的不同處在於排序時是以雙向在序列中進行排序。 
                */    
                public function cocktailSortArr(result:Array):Array {
                        var i:int = 0;
                        var n:int = result.length;
                        var top:int = n - 1;
                        var bottom:int = 0;
                        var swapped:Boolean = true;
                       
                        while(swapped) { // if no elements have been swapped, then the list is sorted
                                swapped = false;
                                var temp:Number;
                                for(i = bottom; i < top;i++) {
                                        if(result[i] > result[i + 1]) {  // test whether the two elements are in the correct order
                                                temp = result[i];// let the two elements change places
                                                result[i] = result[i + 1];
                                                result[i + 1] = temp;
                                                swapped = true;
                                        }
                                }
                                // decreases top the because the element with the largest value in the unsorted
                                // part of the list is now on the position top
                                top = top - 1;
                                for(i = top; i > bottom;i--) {
                                        if(result[i] < result[i - 1]) {
                                                temp = result[i];
                                                result[i] = result[i - 1];
                                                result[i - 1] = temp;
                                                swapped = true;
                                        }
                                }
                                // increases bottom because the element with the smallest value in the unsorted
                                // part of the list is now on the position bottom
                                bottom = bottom + 1; 
                        }
                       
                        return result;
                } 
        }
}