排序算法

一、排序算法說明

  • 排序的定義:對(duì)一序列對(duì)象根據(jù)某個(gè)關(guān)鍵字進(jìn)行排序。
    輸入:n個(gè)數(shù):a1,a2,a3,...,an 輸出:n個(gè)數(shù)的排列:a1',a2',a3',...,an',使得a1'<=a2'<=a3'<=...<=an'
  • 對(duì)于評(píng)述算法優(yōu)劣術(shù)語的說明
  • 穩(wěn)定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;
  • 不穩(wěn)定:如果a原本在b的前面,而a=b,排序之后a可能會(huì)出現(xiàn)在b的后面;
  • 內(nèi)排序:所有排序操作都在內(nèi)存中完成;
  • 外排序:由于數(shù)據(jù)太大,因此把數(shù)據(jù)放在磁盤中,而排序通過磁盤和內(nèi)存的數(shù)據(jù)傳輸才能進(jìn)行;
  • 時(shí)間復(fù)雜度: 一個(gè)算法執(zhí)行所耗費(fèi)的時(shí)間。
  • 空間復(fù)雜度: 運(yùn)行完一個(gè)程序所需內(nèi)存的大小。
  • 總結(jié)
  • 對(duì)比



    In-place: 占用常數(shù)內(nèi)存,不占用額外內(nèi)存 Out-place: 占用額外內(nèi)存。

  • 分類


二、詳解

1.冒泡排序(Bubble Sort)
冒泡排序是一種簡(jiǎn)單的排序算法。它重復(fù)地走訪過要排序的數(shù)列,一次比較兩個(gè)元素,如果它們的順序錯(cuò)誤就把它們交換過來。重復(fù)地進(jìn)行直到?jīng)]有再需要交換,也就是說該數(shù)列已經(jīng)排序完成。

  • 算法描述
    <1>.比較相鄰的元素。如果第一個(gè)比第二個(gè)大,就交換它們兩個(gè);
    <2>.對(duì)每一對(duì)相鄰元素作同樣的工作,從開始第一對(duì)到結(jié)尾的最后一對(duì),這樣在最后的元素應(yīng)該會(huì)是最大的數(shù);
    <3>.針對(duì)所有的元素重復(fù)以上的步驟,除了最后一個(gè);
    <4>.重復(fù)步驟1~3,直到排序完成。
  • 算法實(shí)現(xiàn)
function bubbleSort(arr) {
    let length = arr.length;
    for(let i = 0;i < length-1;i++) {
        for(let j = 0;j < length-1-i;j++) {
            if(arr[j] > arr[j + 1]) { // 相鄰元素對(duì)比
                let temp = arr[j + 1]; // 交換位置
                arr[j + 1] = arr[j]; 
                arr[j] =temp; 
            }
        }
    }
    return arr;
}
let arr = [2, 1, 19, 30, 27];
console.log(bubbleSort(arr))
  • 算法分析
  • 最佳情況
    T(n) = O(n)(數(shù)據(jù)正序)
  • 最差情況
    T(n) = O(n2)(數(shù)據(jù)反序)
  • 平均
    T(n) = O(n2)

2.選擇排序(Selection Sort)
選擇排序(Selection-sort)是一種簡(jiǎn)單直觀的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續(xù)尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

  • 算法描述
  • <1>.初始狀態(tài):無序區(qū)為R[1..n],有序區(qū)為空;
  • <2>.第i趟排序(i=1,2,3...n-1)開始時(shí),當(dāng)前有序區(qū)和無序區(qū)分別為R[1..i-1]和R(i..n)。排序開始時(shí)從無序區(qū)的第一個(gè)開始,對(duì)比后面的,如果遇到比這個(gè)小的,就記錄下位置。該趟排序從當(dāng)前無序區(qū)中選出最小的記錄R[k],將它與無序區(qū)的第1個(gè)記錄R交換,使R[1..i]和R[i+1..n)分別變?yōu)橛涗泜€(gè)數(shù)增加1個(gè)的新有序區(qū)和記錄個(gè)數(shù)減少1個(gè)的新無序區(qū);
  • <3>.n-1趟結(jié)束,數(shù)組有序化了。
  • 算法實(shí)現(xiàn)
function selectionSort(arr) {
    let len = arr.length;
    let minIndex, temp;
    for(let i = 0;i < len;i++) {
        minIndex = i;
        for(let j = i + 1;j < len; j++) {
            if(arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
    console.timeEnd('選擇排序耗時(shí)');
    return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(selectionSort(arr));
  • 算法分析
  • 最佳情況:T(n) = O(n2)
  • 最差情況:T(n) = O(n2)
  • 平均情況:T(n) = O(n2)

3.插入排序(Insertion-Sort)
插入排序(Insertion-Sort)的算法描述是一種簡(jiǎn)單直觀的排序算法。它的工作原理是通過構(gòu)建有序序列,對(duì)于未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應(yīng)位置并插入。

  • 算法描述

  • <1>.從第一個(gè)元素開始,該元素可以認(rèn)為已經(jīng)被排序;

  • <2>.取出下一個(gè)元素,在已經(jīng)排序的元素序列中從后向前掃描;

  • <3>.如果該元素(已排序)大于新元素,將該元素移到下一位置;

  • <4>.重復(fù)步驟3,直到找到已排序的元素小于或者等于新元素的位置;

  • <5>.將新元素插入到該位置后;

  • <6>.重復(fù)步驟2~5。

  • 算法實(shí)現(xiàn)

function insertionSort (array) {
    if(Object.prototype.toString.call(array).slice(8, -1) == 'Array') {
        console.time('插入排序耗時(shí)');
        for (let i = 1;i < array.length; i++) {
            let key = array[i];
            let j = i - 1;
            while(j >= 0 && array[j] > key) {
                array[j + 1] = array[j]; //與前面排好序的對(duì)比
                j--;
            }
            array[j + 1] = key; // 插入到最后對(duì)比的那個(gè)數(shù)后面
        }
        console.timeEnd('插入排序耗時(shí):');
        return array;
    } else {
        return 'array is not an Array!';
    }
}
  • 算法分析
  • 最佳情況:輸入數(shù)組按升序排列。T(n) = O(n)
  • 最壞情況:輸入數(shù)組按降序排列。T(n) = O(n2)
  • 平均情況:T(n) = O(n2)

4.歸并排序(Merge Sort)
和選擇排序一樣,歸并排序的性能不受輸入數(shù)據(jù)的影響,但表現(xiàn)比選擇排序好的多,因?yàn)槭冀K都是O(n log n)的時(shí)間復(fù)雜度。代價(jià)是需要額外的內(nèi)存空間。
歸并排序是建立在歸并操作上的一種有效的排序算法。該算法是采用分治法(Divide and Conquer)的一個(gè)非常典型的應(yīng)用。歸并排序是一種穩(wěn)定的排序方法。將已有序的子序列合并,得到完全有序的序列;即先使每個(gè)子序列有序,再使子序列段間有序。若將兩個(gè)有序表合并成一個(gè)有序表,稱為2-路歸并。

  • 算法描述
  • <1>.把長度為n的輸入序列分成兩個(gè)長度為n/2的子序列;
  • <2>.對(duì)這兩個(gè)子序列分別采用歸并排序;
  • <3>.將兩個(gè)排序好的子序列合并成一個(gè)最終的排序序列。
  • 算法實(shí)現(xiàn)
function mergeSort(arr) {  //采用自上而下的遞歸方法
    var len = arr.length;
    if(len < 2) {
        return arr;
    }
    var middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right)
{
    var result = [];
    console.time('歸并排序耗時(shí)');
    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }
    while (left.length)
        result.push(left.shift());
    while (right.length)
        result.push(right.shift());
    console.timeEnd('歸并排序耗時(shí)');
    return result;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(mergeSort(arr));
  • 算法分析
  • 最佳情況:T(n) = O(n)
  • 最差情況:T(n) = O(nlogn)
  • 平均情況:T(n) = O(nlogn)

5.快速排序(Quick Sort)
快速排序快,而且效率高!它是處理大數(shù)據(jù)最快的排序算法之一。
快速排序的基本思想:通過一趟排序?qū)⒋庞涗浄指舫瑟?dú)立的兩部分,其中一部分記錄的關(guān)鍵字均比另一部分的關(guān)鍵字小,則可分別對(duì)這兩部分記錄繼續(xù)進(jìn)行排序,以達(dá)到整個(gè)序列有序。

  • 算法描述
  • <1>.從數(shù)列中挑出一個(gè)元素,稱為 "基準(zhǔn)"(pivot);
  • <2>.重新排序數(shù)列,所有元素比基準(zhǔn)值小的擺放在基準(zhǔn)前面,所有元素比基準(zhǔn)值大的擺在基準(zhǔn)的后面(相同的數(shù)可以到任一邊)。在這個(gè)分區(qū)退出之后,該基準(zhǔn)就處于數(shù)列的中間位置。這個(gè)稱為分區(qū)(partition)操作;
  • <3>.遞歸地(recursive)把小于基準(zhǔn)值元素的子數(shù)列和大于基準(zhǔn)值元素的子數(shù)列排序。
  • 算法實(shí)現(xiàn)
let quickSort = function (arr) {
    console.time('快速排序耗時(shí)');
    if(arr.length <= 1) {return arr;}
    let pivotIndex = Math.floor(arr.length / 2);
    let pivot = arr.splice(pivotIndex, 1) [0];
    let left = [];
    let right = [];
    for (let i = 0; i < arr.length; i++) {
        if(arr[i] < pivot) {
            left.push(arr[i]);
        } else {
            right.push(arr[i]);
        }
    }
    console.timeEnd('快速排序耗時(shí)');
  return quickSort(left).concat([pivot], quickSort(right));
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(quickSort(arr));
  • 算法分析
  • 最佳情況:T(n) = O(nlogn)
  • 最差情況:T(n) = O(n2)
  • 平均情況:T(n) = O(nlogn)

6.計(jì)數(shù)排序
計(jì)數(shù)排序(Counting sort)是一種穩(wěn)定的排序算法。計(jì)數(shù)排序使用一個(gè)額外的數(shù)組C,其中第i個(gè)元素是待排序數(shù)組A中值等于i的元素的個(gè)數(shù)。然后根據(jù)數(shù)組C來將A中的元素排到正確的位置。它只能對(duì)整數(shù)進(jìn)行排序。

  • 算法描述
  • <1>. 找出待排序的數(shù)組中最大和最小的元素;
  • <2>. 統(tǒng)計(jì)數(shù)組中每個(gè)值為i的元素出現(xiàn)的次數(shù),存入數(shù)組C的第i項(xiàng);
  • <3>. 對(duì)所有的計(jì)數(shù)累加(從C中的第一個(gè)元素開始,每一項(xiàng)和前一項(xiàng)相加);
  • <4>. 反向填充目標(biāo)數(shù)組:將每個(gè)元素i放在新數(shù)組的第C(i)項(xiàng),每放一個(gè)元素就將C(i)減去1。
  • 算法實(shí)現(xiàn)
function countingSort(array) {
    var len = array.length,
        B = [],
        C = [],
        min = max = array[0];
    console.time('計(jì)數(shù)排序耗時(shí)');
    for (var i = 0; i < len; i++) {
        min = min <= array[i] ? min : array[i];
        max = max >= array[i] ? max : array[i];
        C[array[i]] = C[array[i]] ? C[array[i]] + 1 : 1;
    }
    for (var j = min; j < max; j++) {
        C[j + 1] = (C[j + 1] || 0) + (C[j] || 0);
    }
    for (var k = len - 1; k >= 0; k--) {
        B[C[array[k]] - 1] = array[k];
        C[array[k]]--;
    }
    console.timeEnd('計(jì)數(shù)排序耗時(shí)');
    return B;
}
var arr = [2, 2, 3, 8, 7, 1, 2, 2, 2, 7, 3, 9, 8, 2, 1, 4, 2, 4, 6, 9, 2];
console.log(countingSort(arr)); 
  • 算法分析
  • 最佳情況:T(n) = O(n+k)
  • 最差情況:T(n) = O(n+k)
  • 平均情況:T(n) = O(n+k)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,179評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,444評(píng)論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,948評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,185評(píng)論 0 287
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,717評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,794評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,414評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,750評(píng)論 2 370

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

  • Ba la la la ~ 讀者朋友們,你們好啊,又到了冷鋒時(shí)間,話不多說,發(fā)車! 1.冒泡排序(Bub...
    王飽飽閱讀 1,808評(píng)論 0 7
  • 總結(jié)一下常見的排序算法。 排序分內(nèi)排序和外排序。內(nèi)排序:指在排序期間數(shù)據(jù)對(duì)象全部存放在內(nèi)存的排序。外排序:指在排序...
    jiangliang閱讀 1,361評(píng)論 0 1
  • 前些天同學(xué)告訴我要去體檢,問我一起去不去,欣然接受了他的建議,但是他那里有點(diǎn)事要我先去他家正好我們也有段時(shí)間...
    清風(fēng)湖水橋閱讀 320評(píng)論 2 2
  • 算法思想 算法流程 算法步驟 算法實(shí)現(xiàn) python 算法應(yīng)用
    伊凡vnir閱讀 863評(píng)論 0 0
  • 聽老師的話,嘗試用自己的語言開始記錄點(diǎn)什么。不知道從什么時(shí)候開始,心里有過這么一個(gè)念頭,但一直沒有真正的付出...
    知邱一頁閱讀 308評(píng)論 0 1