js實現(xiàn)經(jīng)典排序

選擇排序厕怜、快速排序绑莺、希爾排序、堆排序不是穩(wěn)定的排序算法览妖,
冒泡排序簿盅、插入排序挥下、歸并排序和基數(shù)排序是穩(wěn)定的排序算法。

  • 冒泡法:復(fù)雜度為O(n*n)桨醋。當(dāng)數(shù)據(jù)為正序棚瘟,將不會有交換。復(fù)雜度為O(0)喜最。
  • 直接插入排序:O(n*n)
  • 選擇排序:O(n*n)
  • 快速排序:平均時間復(fù)雜度log2(n)*n
  • 歸并排序:log2(n)*n
  • 堆排序:log2(n)*n
  • 希爾排序:算法的復(fù)雜度為n的1.2次冪

(1)冒泡排序
冒泡排序就是把小的元素往前調(diào)或者把大的元素往后調(diào)偎蘸。比較是相鄰的兩個元素比較,交換也發(fā)生在這兩個元素之間。所以迷雪,如果兩個元素相等限书,我想你是不會再無聊地把他們倆交換一下的;如果兩個相等的元素沒有相鄰章咧,那么即使通過前面的兩兩交換把兩個相鄰起來倦西,這時候也不會交換,所以相同元素的前后順序并沒有改變赁严,所以冒泡排序是一種穩(wěn)定排序算法扰柠。

//冒泡排序
function startBubble (arr) {    
  var length = arr.length;    
  for ( var i = length; i>= 2 ; --i) {        
    for ( var j = 0 ; j<=i+1 ; ++j) {            
      if (arr[j] > arr[j+1]){                
        [arr[j],arr[j+1]] = [arr[j+1],arr[j]];
            }        
        }    
    }
}

(2)選擇排序
選擇排序是給每個位置選擇當(dāng)前元素最小的,比如給第一個位置選擇最小的误澳,在剩余元素里面給第二個元素選擇第二小的耻矮,依次類推秦躯,直到第n-1個元素忆谓,第n個元素不用選擇了,因為只剩下它一個最大的元素了踱承。那么倡缠,在一趟選擇,如果當(dāng)前元素比一個元素小茎活,而該小的元素又出現(xiàn)在一個和當(dāng)前元素相等的元素后面昙沦,那么交換后穩(wěn)定性就被破壞了。比較拗口载荔,舉個例子盾饮,序列5 8 5 2 9, 我們知道第一遍選擇第1個元素5會和2交換懒熙,那么原序列中2個5的相對前后順序就被破壞了丘损,所以選擇排序不是一個穩(wěn)定的排序算法。

//選擇排序
function startSelect (arr) {    
var length = arr.length;
    for ( var i = 0; i <= length-2; ++i ) {
        min = i;
        for ( var j = i+1;j<length-1 ; ++j ) {
            if ( arr[j] < arr[min] ) {
               min = i;            
            }
            [arr[j],arr[i]] = [arr[i],arr[j]];
        }
    }
}

(3)插入排序
插入排序是在一個已經(jīng)有序的小序列的基礎(chǔ)上工扎,一次插入一個元素徘钥。當(dāng)然,剛開始這個有序的小序列只有1個元素肢娘,就是第一個元素呈础。比較是從有序序列的末尾開始,也就是想要插入的元素和已經(jīng)有序的最大者開始比起橱健,如果比它大則直接插入在其后面而钞,否則一直往前找直到找到它該插入的位置。如果碰見一個和插入元素相等的拘荡,那么插入元素把想插入的元素放在相等元素的后面臼节。所以,相等元素的前后順序沒有改變,從原無序序列出去的順序就是排好序后的順序官疲,所以插入排序是穩(wěn)定的袱结。

//插入排序
function startInsert (arr) {
    var temp,inner;
    var length = arr.length;
    for ( var i = 1;i<= length-1 ; ++i) {
        temp = arr[i];
        inner = i;
        while ( inner > 0 && arr[inner-1] >=temp ) {
            arr[inner] = arr[inner-1]; 
           --inner;
        }
        arr[inner]=temp;
    }
}

(4)快速排序
快速排序有兩個方向,左邊的i下標(biāo)一直往右走途凫,當(dāng)a[i] <= a[center_index]垢夹,其中center_index是中樞元素的數(shù)組下標(biāo),一般取為數(shù)組第0個元素维费。而右邊的j下標(biāo)一直往左走果元,當(dāng)a[j] > a[center_index]。如果i和j都走不動了犀盟,i <= j, 交換a[i]和a[j],重復(fù)上面的過程而晒,直到i>j。 交換a[j]和a[center_index]阅畴,完成一趟快速排序倡怎。在中樞元素和a[j]交換的時候,很有可能把前面的元素的穩(wěn)定性打亂贱枣,比如序列為 5 3 3 4 3 8 9 10 11监署, 現(xiàn)在中樞元素5和3(第5個元素,下標(biāo)從1開始計)交換就會把元素3的穩(wěn)定性打亂纽哥,所以快速排序是一個不穩(wěn)定的排序算法钠乏,不穩(wěn)定發(fā)生在中樞元素和a[j]交換的時刻。

(5)歸并排序
歸并排序是把序列遞歸地分成短序列春塌,遞歸出口是短序列只有1個元素(認(rèn)為直接有序)或者2個序列(1次比較和交換),然后把各個有序的段序列合并成一個有序的長序列晓避,不斷合并直到原序列全部排好序≈豢牵可以發(fā)現(xiàn)俏拱,在1個或2個元素時,1個元素不會交換吕世,2個元素如果大小相等也沒有人故意交換彰触,這不會破壞穩(wěn)定性。那么命辖,在短的有序序列合并的過程中况毅,穩(wěn)定是是否受到破壞?沒有尔艇,合并過程中我們可以保證如果兩個當(dāng)前元素相等時尔许,我們把處在前面的序列的元素保存在結(jié)果序列的前面,這樣就保證了穩(wěn)定性终娃。所以味廊,歸并排序也是穩(wěn)定的排序算法。

(6)基數(shù)排序
基數(shù)排序是按照低位先排序,然后收集余佛;再按照高位排序柠新,然后再收集;依次類推辉巡,直到最高位恨憎。有時候有些屬性是有優(yōu)先級順序的,先按低優(yōu)先級排序郊楣,再按高優(yōu)先級排序憔恳,最后的次序就是高優(yōu)先級高的在前,高優(yōu)先級相同的低優(yōu)先級高的在前净蚤≡孔椋基數(shù)排序基于分別排序,分別收集今瀑,所以其是穩(wěn)定的排序算法程梦。

(7)希爾排序(shell)
希爾排序是按照不同步長對元素進(jìn)行插入排序,當(dāng)剛開始元素很無序的時候放椰,步長最大作烟,所以插入排序的元素個數(shù)很少,速度很快砾医;當(dāng)元素基本有序了,步長很小衣厘,插入排序?qū)τ谟行虻男蛄行屎芨呷缪痢K裕柵判虻臅r間復(fù)雜度會比o(n^2)好一些影暴。由于多次插入排序错邦,我們知道一次插入排序是穩(wěn)定的,不會改變相同元素的相對順序型宙,但在不同的插入排序過程中撬呢,相同的元素可能在各自的插入排序中移動,最后其穩(wěn)定性就會被打亂妆兑,所以shell排序是不穩(wěn)定的魂拦。

//希爾排序
function XiEr (arr) {
    var gaps = [5,3,1];
    var gapLength = gaps.length;
    var length = arr.length;
    for( var x = 0; x < gapLength ; ++x ) {
        for ( var i = gaps[x]; i< length ;i++) {
            var temp = arr[i];
            for ( j = i ;j >= gaps[x] && arr[j-gaps[x]] > temp; j-=gaps[x]) {
                arr[j] = arr[j-gaps[x]];
            }
            arr[j] = temp ;
        }
    }
}

(8)堆排序
我們知道堆的結(jié)構(gòu)是節(jié)點i的孩子為2i和2i+1節(jié)點,大頂堆要求父節(jié)點大于等于其2個子節(jié)點搁嗓,小頂堆要求父節(jié)點小于等于其2個子節(jié)點芯勘。在一個長為n的序列,堆排序的過程是從第n/2開始和其子節(jié)點共3個值選擇最大(大頂堆)或者最小(小頂堆),這3個元素之間的選擇當(dāng)然不會破壞穩(wěn)定性腺逛。但當(dāng)為n/2-1, n/2-2, ...1這些個父節(jié)點選擇元素時荷愕,就會破壞穩(wěn)定性。有可能第n/2個父節(jié)點交換把后面一個元素交換過去了,而第n/2-1個父節(jié)點把后面一個相同的元素沒有交換安疗,那么這2個相同的元素之間的穩(wěn)定性就被破壞了抛杨。所以,堆排序不是穩(wěn)定的排序算法

  1. 快速排序(QuickSort)
    快速排序是一個就地排序荐类,分而治之蝶桶,大規(guī)模遞歸的算法。
    從本質(zhì)上來說掉冶,它是歸并排序的就地版本真竖。快速排序可以由下面四步組成厌小。
    (1) 如果不多于1個數(shù)據(jù)恢共,直接返回。
    (2) 一般選擇序列最左邊的值作為支點數(shù)據(jù)璧亚。
    (3) 將序列分成2部分讨韭,一部分都大于支點數(shù)據(jù),另外一部分都小于支點數(shù)據(jù)癣蟋。
    (4) 對兩邊利用遞歸排序數(shù)列透硝。快速排序比大部分排序算法都要快疯搅。盡管我們可以在某些特殊的情況下寫出比快速排序快的算法濒生,但是就通常情況而言,沒有比它更快的了幔欧∽镏危快速排序是遞歸的,對于內(nèi)存非常有限的機(jī)器來說礁蔗,它不是一個好的選擇觉义。

  2. 歸并排序(MergeSort)
    歸并排序先分解要排序的序列,從1分成2浴井,2分成4晒骇,依次分解,當(dāng)分解到只有1個一組的時候磺浙,就可以排序這些分組洪囤,然后依次合并回原來的序列中,這樣就可以排序所有數(shù)據(jù)屠缭。合并排序比堆排序稍微快一點箍鼓,但是需要比堆排序多一倍的內(nèi)存空間,因為它需要一個額外的數(shù)組呵曹。

  3. 堆排序(HeapSort)
    堆排序適合于數(shù)據(jù)量非常大的場合(百萬數(shù)據(jù))款咖。堆排序不需要大量的遞歸或者多維的暫存數(shù)組何暮。這對于數(shù)據(jù)量非常巨大的序列是合適的。比如超過數(shù)百萬條記錄铐殃,因為快速排序海洼,歸并排序都使用遞歸來設(shè)計算法,在數(shù)據(jù)量非常大的時候富腊,可能會發(fā)生堆棧溢出錯誤坏逢。堆排序會將所有的數(shù)據(jù)建成一個堆,最大的數(shù)據(jù)在堆頂赘被,然后將堆頂數(shù)據(jù)和序列的最后一個數(shù)據(jù)交換是整。接下來再次重建堆,交換數(shù)據(jù)民假,依次下去浮入,就可以排序所有的數(shù)據(jù)。

  4. Shell排序(ShellSort)
    Shell排序通過將數(shù)據(jù)分成不同的組羊异,先對每一組進(jìn)行排序事秀,然后再對所有的元素進(jìn)行一次插入排序,以減少數(shù)據(jù)交換和移動的次數(shù)野舶。平均效率是O(nlogn)易迹。其中分組的合理性會對算法產(chǎn)生重要的影響。現(xiàn)在多用D.E.Knuth的分組方法平道。Shell排序比冒泡排序快5倍睹欲,比插入排序大致快2倍。
    Shell排序比起QuickSort巢掺,MergeSort句伶,HeapSort慢很多。但是它相對比較簡單陆淀,它適合于數(shù)據(jù)量在5000以下并且速度并不是特別重要的場合。它對于數(shù)據(jù)量較小的數(shù)列重復(fù)排序是非常好的先嬉。

  5. 插入排序(InsertSort)
    插入排序通過把序列中的值插入一個已經(jīng)排序好的序列中轧苫,直到該序列的結(jié)束。插入排序是對冒泡排序的改進(jìn)疫蔓。它比冒泡排序快2倍含懊。一般不用在數(shù)據(jù)大于1000的場合下使用插入排序,或者重復(fù)排序超過200數(shù)據(jù)項的序列衅胀。

  6. 冒泡排序(BubbleSort)
    冒泡排序是最慢的排序算法岔乔。在實際運用中它是效率最低的算法。它通過一趟又一趟地比較數(shù)組中的每一個元素滚躯,使較大的數(shù)據(jù)下沉雏门,較小的數(shù)據(jù)上升嘿歌。它是O(n^2)的算法。

  7. 交換排序(ExchangeSort)和選擇排序(SelectSort)
    這兩種排序方法都是交換方法的排序算法茁影,效率都是 O(n2)宙帝。在實際應(yīng)用中處于和冒泡排序基本相同的地位。它們只是排序算法發(fā)展的初級階段募闲,在實際中使用較少步脓。

  8. 基數(shù)排序(RadixSort)
    基數(shù)排序和通常的排序算法并不走同樣的路線。它是一種比較新穎的算法浩螺,但是它只能用于整數(shù)的排序靴患,如果我們要把同樣的辦法運用到浮點數(shù)上,我們必須了解浮點數(shù)的存儲格式要出,并通過特殊的方式將浮點數(shù)映射到整數(shù)上鸳君,然后再映射回去,這是非常麻煩的事情厨幻,因此相嵌,它的使用同樣也不多。而且况脆,最重要的是饭宾,這樣算法也需要較多的存儲空間。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末格了,一起剝皮案震驚了整個濱河市看铆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盛末,老刑警劉巖弹惦,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悄但,居然都是意外死亡棠隐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門檐嚣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來助泽,“玉大人,你說我怎么就攤上這事嚎京∥撕兀” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵鞍帝,是天一觀的道長诫睬。 經(jīng)常有香客問我,道長帕涌,這世上最難降的妖魔是什么摄凡? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任续徽,我火速辦了婚禮,結(jié)果婚禮上架谎,老公的妹妹穿的比我還像新娘炸宵。我一直安慰自己,他們只是感情好谷扣,可當(dāng)我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布土全。 她就那樣靜靜地躺著,像睡著了一般会涎。 火紅的嫁衣襯著肌膚如雪裹匙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天末秃,我揣著相機(jī)與錄音概页,去河邊找鬼。 笑死练慕,一個胖子當(dāng)著我的面吹牛惰匙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铃将,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼项鬼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了劲阎?” 一聲冷哼從身側(cè)響起绘盟,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎悯仙,沒想到半個月后龄毡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡锡垄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年沦零,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片货岭。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡蠢终,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茴她,到底是詐尸還是另有隱情,我是刑警寧澤程奠,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布丈牢,位于F島的核電站,受9級特大地震影響瞄沙,放射性物質(zhì)發(fā)生泄漏己沛。R本人自食惡果不足惜慌核,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望申尼。 院中可真熱鬧垮卓,春花似錦、人聲如沸师幕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霹粥。三九已至灭将,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間后控,已是汗流浹背庙曙。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留浩淘,地道東北人捌朴。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像张抄,于是被迫代替她去往敵國和親砂蔽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,440評論 2 348

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

  • 某次二面時欣鳖,面試官問起Js排序問題察皇,吾絞盡腦汁回答了幾種,深感算法有很大的問題泽台,所以總計一下什荣! 排序算法說明 (1...
    流浪的先知閱讀 1,189評論 0 4
  • Ba la la la ~ 讀者朋友們,你們好啊怀酷,又到了冷鋒時間稻爬,話不多說,發(fā)車蜕依! 1.冒泡排序(Bub...
    王飽飽閱讀 1,790評論 0 7
  • 總結(jié)一下常見的排序算法桅锄。 排序分內(nèi)排序和外排序。內(nèi)排序:指在排序期間數(shù)據(jù)對象全部存放在內(nèi)存的排序样眠。外排序:指在排序...
    jiangliang閱讀 1,334評論 0 1
  • 什么決定了你的自我驅(qū)動力 一友瘤、保護(hù)好我的自我驅(qū)動力 如果你現(xiàn)在有某種剛需,一定要記得好好去維護(hù)它檐束,因數(shù)它有可能比想...
    青青wh閱讀 233評論 0 1
  • 堅持學(xué)習(xí)分享第47天被丧。2017年9月2日盟戏,星期六 開學(xué)兩天了绪妹,面對60多個孩子。出現(xiàn)了很多很多的問題柿究。本來信心滿滿...
    奇峰_5114閱讀 272評論 0 0