快速排序

算法思路

選擇一個數字 povit = array[low] 爲關鍵字
目的就是爲了肯定關鍵字所在最終結果中的位置
經過遍歷分區,左分區小於關鍵字,右分區大於關鍵字,關鍵字位置肯定算法

注意

遞歸時一直都是操做的array數組,分區是array的一部分,沒有將分區做爲一個新數組。
分區是用lowhigh再加上關鍵字位置index來計算的數組

時間複雜度

快速排序是不穩定的
平均:O(nlogn)
最壞:O(n²);數組自己有序數據結構

步驟詳解

  • 初始數組
var array = [49, 25, 32, 95, 64, 71, 13]

初始數組

  • 選中最低位爲關鍵字,關鍵字被記錄之後再也不關注array[0]的值,最後將關鍵字放到居中(左邊數字<關鍵字<右邊數字)的位置,即時最終結果該元素所在位置
pivot = array[0]
low = 0
high = 6

選中關鍵字

  • 從右向左遍歷,遇到比關鍵字小的則替換,此時low = 1high = 6array[6]再也不被關注
while (low < high && array[high] >= pivot) {
    high--;
}
array[low] = array[high];

第一次替換

  • 從左向右遍歷,遇到比關鍵字大的則替換,此時low = 3high = 6
while (low < && array[low] <= pivot) {
    low++;
}
array[high] = array[low];

第二次替換

  • 再從右向左遍歷,直到low == high
while (low < high) {
    while (low < high && array[high] <= pivot) {
        high--;
    }
    array[low] = array[high];
    while (low < && array[high] >= pivot) {
        low++;
    }
    array[high] = array[low];
}

low == high

  • 最終肯定關鍵字的位置並將關鍵字賦值到此處,返回該位置;獲得了新的數組,此時關鍵字所在就是最終數組的位置
array[low] = pivot
return low;

返回關鍵字的位置

  • 接下來對對分區數組重複以上步驟,先左後右,一直在改變array,每次都能將關鍵字所在的最終位置肯定

最小分區

  • 退出循環
  1. 關鍵字位置爲 array[low] ,左分區爲空,遞歸時 low > high
  2. 關鍵字位置爲 array[high] ,又分區爲空,遞歸時 low > high
  3. 關鍵字位置爲 low + 1 或者 high -1 ,左或右分區只有一個元素,遞歸時 low == high

完整代碼

function Partition(array, low, high) {
    var pivot = array[low];
    while (low < high) {
        while (low < high && array[high] >= pivot) {
            high--;
        }
        array[low] = array[high];
        while (low < high && array[low] <= pivot) {
            low++;
        }
        array[high] = array[low];
    }

    array[low] = pivot;
    return low;
}

function QuickSort(array, low, high) {
    if (low < high) {
        var index = Partition(array, low, high);
        QuickSort(array, low, index - 1);
        QuickSort(array, index + 1, high);
    }
}

var array = [49, 25, 32, 95, 64, 71, 13];
QuickSort(array, 0, array.length - 1);
console.log(array);

結果

其它寫法1

function QuickSort(array, low, high) {
    if (low < high) {
        //劃分
        pivot = array[low];
        i = low;
        j = high;
        while (i < j) {
            while (i < j && array[j] >= pivot) {
                j--;
            }
            array[i] = array[j]
            while (i < j && array[i] <= pivot) {
                i++;
            }
            array[j] = array[i];
        }
        //確認關鍵字位置
        array[i] = pivot;

        //對分區進行快排
        QuickSort(array, low, i - 1);
        QuickSort(array, i + 1, high);
    }
}

var array = [49, 25, 32, 95, 64, 71, 13];
QuickSort(array, 0, array.length - 1)

結果

其它寫法2

//分區
function Partition(array, length, start, end) {

    if (array == null || length <= 0 || start < 0 || end >= length) {
        consol.log('Invalid Parameters')
    }
    //生成隨機數
    var index = RandomInRange(start, end);
    //交換
    Swap(array[index], array[end]);

    var small = start - 1;
    for (index = start; index < end; ++index) {
        if (data[index] < data[end]) {
            ++small;
            if (small != index) {
                Swap(array[index], array(small));
            }
        }
    }

    ++small;
    Swap(array[small], array[end]);

    return small;

}

function QuickSort(array, length, start, end) {
    if (start == end) {
        return;
    }
    var index = Partition(array, length, start, end);
    if (index > start) {
        QuickSort(array, length, start, end);
    }
    if (index < end) {
        QuickSort(array, length, index + 1, end);
    }

}

var array = [49, 25, 32, 95, 64, 71, 13]
QuickSort(array, array.length, 0, array.length - 1)

參考:
《劍指offer》
《數據結構(C語言版)》 ——嚴蔚敏 吳偉民dom

相關文章
相關標籤/搜索