高級排序(希爾饭庞,快速)

希爾排序

希爾排序(縮小增量法) 屬于插入類排序,是將整個無序列分割成若干小的子序列分別進行插入排序舟山。希爾排序并不穩(wěn)定,O(1)的額外空間累盗,時間復雜度為O(N*(logN)^2)。最壞的情況下的執(zhí)行效率和在平均情況下的執(zhí)行效率相比相差不多符相。
希爾排序間隔序列函數(shù) h = h * 3+ 1
希爾排序比插入排序快很多的原因:當h值很大時蠢琳,數(shù)據(jù)項每一趟排序移動的元素個數(shù)少,但移動的距離很長傲须,這是非常高效的;當h值減小時例衍,每一趟排序移動的元素個數(shù)增加已卸,但此時的數(shù)據(jù)項已經(jīng)接近于他們最終排序后的位置,插入排序可以更有效

Paste_Image.png
public class ShellSort {  
    static void sort(int[] array) {  
        int out, in, tmp;  
        int len = array.length;  
        int h = 1;   
        while(h < len / 3) // 計算間隔h最大值  
            h = h * 3 + 1;  
          
        while(h > 0){ // 能否繼續(xù)通過縮小間隔h來分割數(shù)據(jù)列的判定  
            /* 
             * out為什么從h開始梦抢?你分割后的第一子序列應該是這樣一個序列永乌,0, h, 2h, 3h, ... 
             * 插入排序的while循環(huán)是從1開始的,因為第一個數(shù)始終有序圈驼,不需要比較望几,這個需要了解插入排序的算法,所以比較是從第二個數(shù)據(jù)線橄抹,就是數(shù)組的第h個下標開始 
             * out的判定為什么是out < len? 
             * 控制數(shù)組下標玉锌,下面的例子會說道 
             *  
             * 下面舉一個例子來解釋 
             * 假定有一個10個數(shù)據(jù)項的數(shù)組疟羹,數(shù)組下標從0 ~ 9 表示 
             * 當h = 4時的子序列情況是這樣的禀倔,以下標表示 
             * (0 4 8)(1 5 9)(2 6)(3 7) 
             * 我第一次是這么理解的参淫,真對每一組分別進行插入排序(當然也可以這樣實現(xiàn),但是下標不好控制)鞋既,但是對下面的代碼來說這是錯誤的理解耍铜。 
             * 正確的過程是這樣的,外層for循環(huán)每次對每一分組的前兩個數(shù)據(jù)項進行插入排序业扒,然后前3個,然后前4個 ... 這個和子序列個數(shù)有關 
             * 排序過程只真對方括號進行 
             * 當out = 4時進行如下過程 ([0 4] 8) 
             * 當out = 5時([1 5] 9) 
             * 當out = 6時([2 6]) 
             * 當out = 7時([3 7]) 
             * 當out = 8時([0 4 8]) 
             * 當out = 9時([1 5 9]) 
             * h = 4執(zhí)行完畢,然后h = (h - 1) / 3 = 1開始新的for循環(huán) 
             * h = 1時執(zhí)行過程和h = 4時一樣章鲤,不過這時的子數(shù)列就是原始的數(shù)列咆贬,蛻變?yōu)橐粋€簡單的插入排序,這是數(shù)組基本有序掏缎,數(shù)據(jù)項移動次數(shù)會大大減少 
             *  
             */  
            for(out = h; out < len; out++){ // 外層通過out確定每組插入排序的第二個數(shù)據(jù)項  
                // 以下代碼就是對子序列進行的插入排序算法  
                tmp = array[out];  
                in = out;  
                /* 
                 * 比較插入排序while循環(huán)的寫法,這里的while循環(huán)與h有關沪哺,所以判定就與h有關酌儒,包括 in -= h語句 
                 * while(in > 0 && array[in - 1] > tmp){ 
                 * array[in] = array[in - 1]; 
                 * in--; 
                 * } 
                 * array[in] = tmp; 
                 *  
                 */  
                while(in > h -1 && array[in - h] >= tmp){  
                    array[in] = array[in - h];  
                    in -= h;  
                }  
                array[in] = tmp;  
            }  
              
            // 縮小間隔  
            h = (h - 1) / 3;  
        }  
    }  
}  

快速排序

算法思想:基于分治的思想,是冒泡排序的改進型籍滴。首先在數(shù)組中選擇一個基準點(該基準點的選取可能影響快速排序的效率榴啸,后面講解選取的方法),然后分別從數(shù)組的兩端掃描數(shù)組勋功,設兩個指示標志(lo指向起始位置坦报,hi指向末尾)燎竖,首先從后半部分開始要销,如果發(fā)現(xiàn)有元素比該基準點的值小,就交換lo和hi位置的值疏咐,然后從前半部分開始掃秒,發(fā)現(xiàn)有元素大于基準點的值借跪,就交換lo和hi位置的值酌壕,如此往復循環(huán),直到lo>=hi,然后把基準點的值放到hi這個位置卵牍。一次排序就完成了。以后采用遞歸的方式分別對前半部分和后半部分排序辛掠,當前半部分和后半部分均有序時該數(shù)組就自然有序了释牺。
快速排序的時間復雜度為O(NlogN).

Paste_Image.png
public static int partition(int []array,int lo,int hi){
        //固定的切分方式
        int key=array[lo];//分組最右端為基準值
        while(lo<hi){
            while(array[hi]>=key&&hi>lo){//從后半部分向前掃描
                hi--;
            }
            array[lo]=array[hi];
            while(array[lo]<=key&&hi>lo){從前半部分向后掃描
                lo++;
            }
            array[hi]=array[lo];
        }
        array[hi]=key;
        return hi;
    }
    
    public static void sort(int[] array,int lo ,int hi){
        if(lo>=hi){
            return ;
        }
        int index=partition(array,lo,hi);
        sort(array,lo,index-1);
        sort(array,index+1,hi); 
    }

快速排序的優(yōu)化

對于基準位置的選取一般有三種方法:固定切分没咙,隨機切分和三取樣切分。固定切分的效率并不是太好镜撩,隨機切分是常用的一種切分,效率比較高宜鸯,最壞情況下時間復雜度有可能為O(N2).對于三數(shù)取中選擇基準點是最理想的一種遮怜。
下列代碼替換每個分組基準值

//三數(shù)取中
        int mid=lo+(hi-lo)/2;
        if(array[mid]>array[hi]){
            swap(array[mid],array[hi]);
        }
        if(array[lo]>array[hi]){
            swap(array[lo],array[hi]);
        }
        if(array[mid]>array[lo]){
            swap(array[mid],array[lo]);
        }
        int key=array[lo];

鏈接
希爾:http://blog.csdn.net/zhqingyun163/article/details/8961396
快排:http://www.cnblogs.com/coderising/p/5708801.html

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锯梁,一起剝皮案震驚了整個濱河市焰情,隨后出現(xiàn)的幾起案子剥懒,更是在濱河造成了極大的恐慌,老刑警劉巖初橘,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件保檐,死亡現(xiàn)場離奇詭異,居然都是意外死亡夜只,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門场躯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旅挤,“玉大人,你說我怎么就攤上這事谦铃【匀颍” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵嘹朗,是天一觀的道長诵肛。 經(jīng)常有香客問我,道長褪秀,這世上最難降的妖魔是什么薛训? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮闸英,結果婚禮上锯岖,老公的妹妹穿的比我還像新娘甫何。我一直安慰自己,他們只是感情好捶牢,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布加派。 她就那樣靜靜地躺著,像睡著了一般竹勉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上次乓,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天孽水,我揣著相機與錄音,去河邊找鬼杏慰。 笑死炼鞠,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的谒主。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼擎颖,長吁一口氣:“原來是場噩夢啊……” “哼观游!你這毒婦竟也來了?” 一聲冷哼從身側響起异旧,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤提佣,失蹤者是張志新(化名)和其女友劉穎荤崇,沒想到半個月后潮针,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡瓣戚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年焦读,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仑嗅。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡张症,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出俗他,到底是詐尸還是另有隱情,我是刑警寧澤地沮,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布羡亩,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏专挪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一速侈、第九天 我趴在偏房一處隱蔽的房頂上張望迫卢。 院中可真熱鬧,春花似錦乾蛤、人聲如沸捅僵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馒闷。三九已至叁征,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捺疼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工议薪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留媳友,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓哼御,卻偏偏與公主長得像焊唬,于是被迫代替她去往敵國和親恋昼。 傳聞我的和親對象是個殘疾皇子赶促,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 最近在讀< >時,了解到了很多常用的排序算法,故寫一篇讀書筆記記錄下這些排序算法的思路和實現(xiàn). 冒泡排序 冒泡排序...
    SylvanasSun閱讀 693評論 0 0
  • 冒泡排序 冒泡排序相對來說是較為簡單的一種排序嗦哆,它的思想就是在每一次循環(huán)中比較相鄰的兩個數(shù),通過交換的方式老速,將最小...
    陌上疏影涼閱讀 588評論 0 3
  • 算法簡介 是一種分治的排序算法凸主,特點就是快,而且效率高旁舰。 基本思路 通過一趟排序將待排元素分隔成獨立的兩部分锋华,其中...
    TinyDolphin閱讀 3,492評論 0 3
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,262評論 0 2
  • 最近感覺有點焦慮。上次感覺這么焦慮的時候坊罢,一個我很信任的朋友對我說,你只要做點能讓周圍的人認可的自己擅長的小事就好...
    李猹猹閱讀 459評論 0 1