前端常見(jiàn)的排序算法算法

冒泡排序

我們先來(lái)了解一下冒泡排序算法砌们,它是最慢的排序算法之一,但也是一種最容易實(shí)現(xiàn)的排
序算法瘟判。
之所以叫冒泡排序是因?yàn)槭褂眠@種排序算法排序時(shí)怨绣,數(shù)據(jù)值會(huì)像氣泡一樣從數(shù)組的一端漂浮到另一端。假設(shè)正在將一組數(shù)字按照升序排列拷获,較大的值會(huì)浮動(dòng)到數(shù)組的右側(cè)篮撑,而較小的值則會(huì)浮動(dòng)到數(shù)組的左側(cè)。之所以會(huì)產(chǎn)生這種現(xiàn)象是因?yàn)樗惴〞?huì)多次在數(shù)組中移動(dòng)匆瓜,比較相鄰的數(shù)據(jù)赢笨,當(dāng)左側(cè)值大于右側(cè)值時(shí)將它們進(jìn)行互換未蝌。

代碼實(shí)現(xiàn)

function swap(i,j,array){
  let temp = array[j];
  array[j] = array[i];
  array[i] = temp;
}

function bubbleSort(data) {
  let length = data.length, isSwap;
  for (var i = 0; i < length; i++) {            //正序
    isSwap = false;
    for (var j = 0; j < length - 1 - i; j++) {     //正序
      array[j] > array[j+1] && (isSwap = true) && swap(j,j+1,array);
    }
    if(!isSwap)
      break;
  }
  return data;
}

選擇排序

我們接下來(lái)要看的是選擇排序算法。選擇排序從數(shù)組的開(kāi)頭開(kāi)始茧妒,將第一個(gè)元素和其他元素進(jìn)行比較萧吠。檢查完所有元素后,最小的元素會(huì)被放到數(shù)組的第一個(gè)位置桐筏,然后算法會(huì)從第二個(gè)位置繼續(xù)纸型。這個(gè)過(guò)程一直進(jìn)行,當(dāng)進(jìn)行到數(shù)組的倒數(shù)第二個(gè)位置時(shí)梅忌,所有的數(shù)據(jù)便完成了排序狰腌。
選擇排序會(huì)用到嵌套循環(huán)。外循環(huán)從數(shù)組的第一個(gè)元素移動(dòng)到倒數(shù)第二個(gè)元素牧氮;內(nèi)循環(huán)從第二個(gè)數(shù)組元素移動(dòng)到最后一個(gè)元素琼腔,查找比當(dāng)前外循環(huán)所指向的元素小的元素。每次內(nèi)循環(huán)迭代后踱葛,數(shù)組中最小的值都會(huì)被賦值到合適的位置

代碼實(shí)現(xiàn)

function selectSort(data) {
    let length = data.length;
    let min = 0;
    for(let i = 0; i < length; i++){
        min = i;
        for(let j = i +1; j < length; j++){
            if(data[min] > data[j]){
                swap(min,j,data)
            }
        }
    }
  return data
}

插入排序

插入排序類似于人類按數(shù)字或字母順序?qū)?shù)據(jù)進(jìn)行排序丹莲。例如,讓班里的每個(gè)學(xué)生上交一張寫有他的名字尸诽、學(xué)生證號(hào)以及個(gè)人簡(jiǎn)介的索引卡片甥材。學(xué)生交上來(lái)的卡片是沒(méi)有順序的,但是我想讓這些卡片按字母順序排好逊谋,這樣就可以很容易地與班級(jí)花名冊(cè)進(jìn)行對(duì)照了擂达。我將卡片帶回辦公室,清理好書(shū)桌胶滋,然后拿起第一張卡片”螅卡片上的姓氏是 Smith 究恤。我把它放到桌子的左上角,然后再拿起第二張卡片后德。這張卡片上的姓氏是 Brown 部宿。我把 Smith移右,把 Brown 放到 Smith 的前面瓢湃。下一張卡片是 Williams 理张,可把它放到桌面最右邊,而不用移動(dòng)其他任何卡片绵患。下一張卡片是 Acklin 雾叭。這張卡片必須放在這些卡片的最前面,因此其他所有卡片必須向右移動(dòng)一個(gè)位置來(lái)為 Acklin 這張卡片騰出位置落蝙。這就是插入排序的排序原理织狐。

代碼實(shí)現(xiàn)

function insertSort(data) {
    let length = data.length;
    let index,current;
    for(let i = 0; i<length; i++){
        index = i;
        current = data[i];
        while(index>=0 && (data[index+1] < data[index])){
            swap(index, index+1, data);
            index--;
        }
    }
  return data
}

希爾排序

希爾排序是以它的創(chuàng)造者(Donald Shell)命名的暂幼。這個(gè)算法在插入排序的基礎(chǔ)上做了很大的改善。希爾排序的核心理念與插入排序不同移迫,它會(huì)首先比較距離較遠(yuǎn)的元素旺嬉,而非相鄰的元素。和簡(jiǎn)單地比較相鄰元素相比厨埋,使用這種方案可以使離正確位置很遠(yuǎn)的元素更快地回到合適的位置邪媳。當(dāng)開(kāi)始用這個(gè)算法遍歷數(shù)據(jù)集時(shí),所有元素之間的距離會(huì)不斷減小荡陷,直到處理到數(shù)據(jù)集的末尾雨效,時(shí)算法比較的就是相鄰元素了。
希爾排序的工作原理是亲善,通過(guò)定義一個(gè)間隔序列來(lái)表示在排序過(guò)程中進(jìn)行比較的元素之間有多遠(yuǎn)的間隔设易。我們可以動(dòng)態(tài)定義間隔序列,不過(guò)對(duì)于大部分的實(shí)際應(yīng)用場(chǎng)景蛹头,算法要用到的間隔序列可以提前定義好顿肺。有一些公開(kāi)定義的間隔序列,使用它們會(huì)得到不同的結(jié)果渣蜗。在這里我們用到了 Marcin Ciura 在他 2001 年發(fā)表的論文“Best Increments for theAverage Case of Shell Sort”(http:bit.ly/1b04YFv,2001)中定義的間隔序列屠尊。這個(gè)間隔序列是: 701, 301, 132, 57, 23, 10, 4, 1 。

代碼實(shí)現(xiàn)

function shellsort(data) {
    let gap = Math.floor(data.length/2);
    while(gap>=1){
        for(let i = gap; i<data.length; i++){
            if(data[i]<data[i-gap]){
                swap(i-gap, i, data);
                shellTime += 1;
            }
        }
        gap = gap/2;
    }
  return data
}

歸并排序

歸并排序的命名來(lái)自它的實(shí)現(xiàn)原理:把一系列排好序的子序列合并成一個(gè)大的完整有序序列耕拷。從理論上講讼昆,這個(gè)算法很容易實(shí)現(xiàn)。我們需要兩個(gè)排好序的子數(shù)組骚烧,然后通過(guò)比較數(shù)據(jù)大小浸赫,先從最小的數(shù)據(jù)開(kāi)始插入,最后合并得到第三個(gè)數(shù)組赃绊。然而既峡,在實(shí)際情況中,歸并排序還有一些問(wèn)題碧查,當(dāng)我們用這個(gè)算法對(duì)一個(gè)很大的數(shù)據(jù)集進(jìn)行排序時(shí)运敢,我們需要相當(dāng)大的空間來(lái)合并存儲(chǔ)兩個(gè)子數(shù)組。就現(xiàn)在來(lái)講忠售,內(nèi)存不那么昂貴传惠,空間不是問(wèn)題,因此值得我們?nèi)?shí)現(xiàn)一下歸并排序稻扬,比較它和其他排序算法的執(zhí)行效率卦方。

代碼實(shí)現(xiàn)

function mergeSort(data) {
    if(data.length < 2){
        return data
    }else{
        let mid = Math.floor(data.length/2);
        let left = data.slice(0, mid);
        let right = data.slice(mid);
        return merge(mergeSort(left), mergeSort(right));
    }
}
function merge(left, right) {
    let arr = [];
    while(left.length > 0 && right.length > 0){
        if(left[0] > right[0]) {
            arr.push(right.shift())
        }else{
            arr.push(left.shift())
        }
    }
    return arr.concat(left, right);
}

快速排序

快速排序是處理大數(shù)據(jù)集最快的排序算法之一。它是一種分而治之的算法腐螟,通過(guò)遞歸的方式將數(shù)據(jù)依次分解為包含較小元素和較大元素的不同子序列愿汰。該算法不斷重復(fù)這個(gè)步驟直到所有數(shù)據(jù)都是有序的困后。
這個(gè)算法首先要在列表中選擇一個(gè)元素作為基準(zhǔn)值(pivot)。數(shù)據(jù)排序圍繞基準(zhǔn)值進(jìn)行衬廷,將列表中小于基準(zhǔn)值的元素移到數(shù)組的底部摇予,將大于基準(zhǔn)值的元素移到數(shù)組的頂部。

代碼實(shí)現(xiàn)

function quickSort(data) {
    if(data.length === 0){
        return []
    }
    let lesser = [];
    let greater = [];
    let pivot = data[0];
    for(let i = 1; i<data.length; i++){
        if(data[i] < pivot){
            lesser.push(data[i]);
        }else{
            greater.push(data[i]);
        }
    }
    return quickSort(lesser).concat(pivot,quickSort(greater))
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吗跋,一起剝皮案震驚了整個(gè)濱河市侧戴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌跌宛,老刑警劉巖酗宋,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異疆拘,居然都是意外死亡蜕猫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門哎迄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)回右,“玉大人,你說(shuō)我怎么就攤上這事漱挚∠杷福” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵旨涝,是天一觀的道長(zhǎng)蹬屹。 經(jīng)常有香客問(wèn)我,道長(zhǎng)白华,這世上最難降的妖魔是什么慨默? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮弧腥,結(jié)果婚禮上业筏,老公的妹妹穿的比我還像新娘。我一直安慰自己鸟赫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布消别。 她就那樣靜靜地躺著抛蚤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪寻狂。 梳的紋絲不亂的頭發(fā)上岁经,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音蛇券,去河邊找鬼缀壤。 笑死樊拓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的塘慕。 我是一名探鬼主播筋夏,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼图呢!你這毒婦竟也來(lái)了条篷?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蛤织,失蹤者是張志新(化名)和其女友劉穎赴叹,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體指蚜,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡啼止,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了斑司。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亚皂。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柱宦,靈堂內(nèi)的尸體忽然破棺而出些椒,到底是詐尸還是另有隱情,我是刑警寧澤掸刊,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布免糕,位于F島的核電站,受9級(jí)特大地震影響忧侧,放射性物質(zhì)發(fā)生泄漏石窑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一蚓炬、第九天 我趴在偏房一處隱蔽的房頂上張望松逊。 院中可真熱鬧,春花似錦肯夏、人聲如沸经宏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)烁兰。三九已至,卻和暖如春徊都,著一層夾襖步出監(jiān)牢的瞬間沪斟,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工暇矫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留主之,地道東北人择吊。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像槽奕,于是被迫代替她去往敵國(guó)和親几睛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355