高速排序

針對冒泡排序咱們進行一次優化,就引進了高速排序在此基礎上進行優化算法

基本思想:

  • 任取一個記錄(如第一個)做爲 樞軸或支點,設其keyword爲pivotkey。markdown

  • 在一趟排序後。所有比它小的記錄一概前放,比它大的記錄一概後放,造成左右兩個子表,將樞軸放在分界處的位置;post

  • 而後。分別對各子表又一次選擇樞軸,並依此規則調整。直到每個子表的元素僅僅剩一個。排序完畢。學習

詳細操做

(1)附設兩個指針low和high,初始時分別指向表的上限和下限。設樞軸記錄的keyword爲pivotkey(第一趟時,low=1。high=L.length)優化

(2)從表的最右側位置。依次向左搜索找到第一個keyword小於pivotkey的記錄和樞軸記錄交換。ui

詳細操做:當.net

low<high時。若high所指紀錄的keyword大於等於pivotkey,則向左移動指針high(即–high)。不然high所指紀指針

錄與樞軸紀錄交換。code

(3)而後再從表的左側位置。依次向右搜索第一個keyword大於pivotkey的記錄和樞軸記錄交換。詳細操做:當low<high時,若low所指記錄的keyword小等於pivotkey,則向右移動指針low(即++low),不然low所指記錄與樞軸記錄交換。對象

(4)反覆(2)(3)步驟,直到low和high相等爲止,此時low或high的位置即爲樞軸在此趟排序中的終於位置。原表被分紅兩個子表。

這裏寫圖片描寫敘述
這裏寫圖片描寫敘述

  • 每一趟的子表的造成是採用從兩頭向中間交替式逼近法;

  • 由於每趟中對各子表的操做都相似。可採用遞歸算法。

    int Partition(SqList &L,int low,int high)
    {
        L.r[0]=L.r[low];
        pivotkey=L.r[low].Key;
        while(low<high)
    {
         while(low<high&&L.r[high].Key>=pivotkey)--high;
         L.r[low]=L.r[high];
     while(low<high&&L.r[low].key<pivotkey)++low;
    }
     L.r[high]=L.r[low];
         return low;
    }
    void QSort(SqList &L,int low,int high)
    {
        if(low<high)
    {
        pivotloc=Partition(L,low,high);
        QSort(L,low,pivotloc-1);
        QSort(L,pivotloc+1,high);
    }
    }
        void QuickSort()
        {
        QSort(L,1,L.length);
    }

算法分析可以證實,平均計算時間是O(nlog2n)。

實驗結果證實:就平均計算時間而言,高速排序是咱們所學習的所有內排序方法中最好的一個。

高速排序是遞歸的,需要有一個棧存放每層遞歸調用時參數(新的low和high)。

最大遞歸調用層次數與遞歸樹的深度一致。所以要求存儲開銷爲O(log2n)。

最好:劃分後,左側右側子序列的長度一樣

最壞:從小到大排好序。遞歸樹成單支樹,每次劃分僅僅獲得一個比上一次少一個對象的子序列。必須通過n-1
趟才幹把所有對象定位,而且第i趟需要通過n-i次關鍵碼比較才幹找到第i個對象的安放位置

時間效率:O(nlog2n)—-每趟肯定的元素呈指數添加

空間效率:O(log2n)—–遞歸要用到棧空間

穩定性:不穩定—–可選任一元素爲支點。

相關文章
相關標籤/搜索