1. 程式人生 > >非遞迴的快速排序

非遞迴的快速排序

對於非遞迴的快速排序,推薦使用棧,和遞迴的快速排序都是不斷的去調整每次遍歷的空間,並通過區間的目標值,一般取區間的第一個值來進行左右區間的劃分,再遞迴呼叫Partition,和遞迴不同的是使用棧可以成對的進行管理區間,每次Partition都會都會得到一個目標值,這個目標值和你之前儲存在棧中的區間範圍可以做判斷,當它和你的左區間長度大於2時,則認為可以進行下一次的Partition併入棧,同理當它和你的右區間長度大於2也是如此。因為你每次都是成對的去儲存你的區間所以對於每次取也應該成對的把區間取出來,當你的棧為空時則排序完成。

程式碼如下:

 public static void QuickSortNoRecursion(int[]arr, int left, int right) {
            Stack<int> partitionRange = new Stack<int>();

            if (left < right) {
                partitionRange.Push(right);     //先進大的數,再進小的數,儲存的是範圍
                partitionRange.Push(left);      

                while (partitionRange.Count > 0) {
                    int i = partitionRange.Pop();   //左區間  
                    int j = partitionRange.Pop();   //右區間
                    int index = Partiton(arr, i, j);
                    if (index > i + 1) {
                        partitionRange.Push(index - 1);
                        partitionRange.Push(i);
                    }
                    if (index < j - 1) {
                        partitionRange.Push(j);
                        partitionRange.Push(index + 1);
                    }
                }
            }

        }
        //一次Partition 調整當前區間的數 比target大的在它右邊,比他小的在它左邊
        public static int Partiton(int[] arr, int left, int right) {
            int target = arr[left];
            while (left < right) {
                while (left < right && target <= arr[right])
                    right--;
                arr[left] = arr[right];
                while (left < right && target >= arr[left])
                    left++;
                arr[right] = arr[left];
            }
            arr[left] = target;
            return left;
        }