国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript 數(shù)據(jù)結(jié)構(gòu)與算法之美 - 歸并排序、快速排序、希爾排序、堆排序

haitiancoder / 3483人閱讀

摘要:之所以把歸并排序快速排序希爾排序堆排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。歸并排序是一種穩(wěn)定的排序方法。因此,快速排序并不穩(wěn)定。希爾排序思想先將整個(gè)待排序的記錄序列分割成為若干子序列。

1. 前言
算法為王。

想學(xué)好前端,先練好內(nèi)功,只有內(nèi)功深厚者,前端之路才會走得更遠(yuǎn)

筆者寫的 JavaScript 數(shù)據(jù)結(jié)構(gòu)與算法之美 系列用的語言是 JavaScript ,旨在入門數(shù)據(jù)結(jié)構(gòu)與算法和方便以后復(fù)習(xí)。

之所以把歸并排序、快速排序、希爾排序、堆排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為 O(nlogn)

請大家?guī)е鴨栴}:快排和歸并用的都是分治思想,遞推公式和遞歸代碼也非常相似,那它們的區(qū)別在哪里呢 ? 來閱讀下文。

2. 歸并排序(Merge Sort)

思想

排序一個(gè)數(shù)組,我們先把數(shù)組從中間分成前后兩部分,然后對前后兩部分分別排序,再將排好序的兩部分合并在一起,這樣整個(gè)數(shù)組就都有序了。

歸并排序采用的是分治思想

分治,顧名思義,就是分而治之,將一個(gè)大問題分解成小的子問題來解決。小的子問題解決了,大問題也就解決了。

注:x >> 1 是位運(yùn)算中的右移運(yùn)算,表示右移一位,等同于 x 除以 2 再取整,即 x >> 1 === Math.floor(x / 2) 。

實(shí)現(xiàn)

const mergeSort = arr => {
    //采用自上而下的遞歸方法
    const len = arr.length;
    if (len < 2) {
        return arr;
    }
    // length >> 1 和 Math.floor(len / 2) 等價(jià)
    let middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle); // 拆分為兩個(gè)子數(shù)組
    return merge(mergeSort(left), mergeSort(right));
};

const merge = (left, right) => {
    const result = [];

    while (left.length && right.length) {
        // 注意: 判斷的條件是小于或等于,如果只是小于,那么排序?qū)⒉环€(wěn)定.
        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());

    return result;
};

測試

// 測試
const arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48];
console.time("歸并排序耗時(shí)");
console.log("arr :", mergeSort(arr));
console.timeEnd("歸并排序耗時(shí)");
// arr : [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
// 歸并排序耗時(shí): 0.739990234375ms

分析

第一,歸并排序是原地排序算法嗎 ?

這是因?yàn)闅w并排序的合并函數(shù),在合并兩個(gè)有序數(shù)組為一個(gè)有序數(shù)組時(shí),需要借助額外的存儲空間。
實(shí)際上,盡管每次合并操作都需要申請額外的內(nèi)存空間,但在合并完成之后,臨時(shí)開辟的內(nèi)存空間就被釋放掉了。在任意時(shí)刻,CPU 只會有一個(gè)函數(shù)在執(zhí)行,也就只會有一個(gè)臨時(shí)的內(nèi)存空間在使用。臨時(shí)內(nèi)存空間最大也不會超過 n 個(gè)數(shù)據(jù)的大小,所以空間復(fù)雜度是 O(n)。
所以,歸并排序不是原地排序算法。

第二,歸并排序是穩(wěn)定的排序算法嗎 ?

merge 方法里面的 left[0] <= right[0] ,保證了值相同的元素,在合并前后的先后順序不變。歸并排序是一種穩(wěn)定的排序方法。

第三,歸并排序的時(shí)間復(fù)雜度是多少 ?

從效率上看,歸并排序可算是排序算法中的佼佼者。假設(shè)數(shù)組長度為 n,那么拆分?jǐn)?shù)組共需 logn 步, 又每步都是一個(gè)普通的合并子數(shù)組的過程,時(shí)間復(fù)雜度為 O(n),故其綜合時(shí)間復(fù)雜度為 O(nlogn)。
最佳情況:T(n) = O(nlogn)。
最差情況:T(n) = O(nlogn)。
平均情況:T(n) = O(nlogn)。

動畫

3. 快速排序 (Quick Sort)

快速排序的特點(diǎn)就是快,而且效率高!它是處理大數(shù)據(jù)最快的排序算法之一。

思想

先找到一個(gè)基準(zhǔn)點(diǎn)(一般指數(shù)組的中部),然后數(shù)組被該基準(zhǔn)點(diǎn)分為兩部分,依次與該基準(zhǔn)點(diǎn)數(shù)據(jù)比較,如果比它小,放左邊;反之,放右邊。

左右分別用一個(gè)空數(shù)組去存儲比較后的數(shù)據(jù)。

最后遞歸執(zhí)行上述操作,直到數(shù)組長度 <= 1;

特點(diǎn):快速,常用。

缺點(diǎn):需要另外聲明兩個(gè)數(shù)組,浪費(fèi)了內(nèi)存空間資源。

實(shí)現(xiàn)

方法一:

const quickSort1 = arr => {
    if (arr.length <= 1) {
        return arr;
    }
    //取基準(zhǔn)點(diǎn)
    const midIndex = Math.floor(arr.length / 2);
    //取基準(zhǔn)點(diǎn)的值,splice(index,1) 則返回的是含有被刪除的元素的數(shù)組。
    const valArr = arr.splice(midIndex, 1);
    const midIndexVal = valArr[0];
    const left = []; //存放比基準(zhǔn)點(diǎn)小的數(shù)組
    const right = []; //存放比基準(zhǔn)點(diǎn)大的數(shù)組
    //遍歷數(shù)組,進(jìn)行判斷分配
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] < midIndexVal) {
            left.push(arr[i]); //比基準(zhǔn)點(diǎn)小的放在左邊數(shù)組
        } else {
            right.push(arr[i]); //比基準(zhǔn)點(diǎn)大的放在右邊數(shù)組
        }
    }
    //遞歸執(zhí)行以上操作,對左右兩個(gè)數(shù)組進(jìn)行操作,直到數(shù)組長度為 <= 1
    return quickSort1(left).concat(midIndexVal, quickSort1(right));
};
const array2 = [5, 4, 3, 2, 1];
console.log("quickSort1 ", quickSort1(array2));
// quickSort1: [1, 2, 3, 4, 5]

方法二:

// 快速排序
const quickSort = (arr, left, right) => {
    let len = arr.length,
        partitionIndex;
    left = typeof left != "number" ? 0 : left;
    right = typeof right != "number" ? len - 1 : right;

    if (left < right) {
        partitionIndex = partition(arr, left, right);
        quickSort(arr, left, partitionIndex - 1);
        quickSort(arr, partitionIndex + 1, right);
    }
    return arr;
};

const partition = (arr, left, right) => {
    //分區(qū)操作
    let pivot = left, //設(shè)定基準(zhǔn)值(pivot)
        index = pivot + 1;
    for (let i = index; i <= right; i++) {
        if (arr[i] < arr[pivot]) {
            swap(arr, i, index);
            index++;
        }
    }
    swap(arr, pivot, index - 1);
    return index - 1;
};

const swap = (arr, i, j) => {
    let temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
};

測試

// 測試
const array = [5, 4, 3, 2, 1];
console.log("原始array:", array);
const newArr = quickSort(array);
console.log("newArr:", newArr);
// 原始 array: ?[5, 4, 3, 2, 1]
// newArr: ?   [1, 4, 3, 2, 5]

分析

第一,快速排序是原地排序算法嗎 ?

因?yàn)?partition() 函數(shù)進(jìn)行分區(qū)時(shí),不需要很多額外的內(nèi)存空間,所以快排是原地排序算法。

第二,快速排序是穩(wěn)定的排序算法嗎 ?

和選擇排序相似,快速排序每次交換的元素都有可能不是相鄰的,因此它有可能打破原來值為相同的元素之間的順序。因此,快速排序并不穩(wěn)定。

第三,快速排序的時(shí)間復(fù)雜度是多少 ?

極端的例子:如果數(shù)組中的數(shù)據(jù)原來已經(jīng)是有序的了,比如 1,3,5,6,8。如果我們每次選擇最后一個(gè)元素作為 pivot,那每次分區(qū)得到的兩個(gè)區(qū)間都是不均等的。我們需要進(jìn)行大約 n 次分區(qū)操作,才能完成快排的整個(gè)過程。每次分區(qū)我們平均要掃描大約 n / 2 個(gè)元素,這種情況下,快排的時(shí)間復(fù)雜度就從 O(nlogn) 退化成了 O(n2)。
最佳情況:T(n) = O(nlogn)。
最差情況:T(n) = O(n2)。
平均情況:T(n) = O(nlogn)。

動畫

解答開篇問題

快排和歸并用的都是分治思想,遞推公式和遞歸代碼也非常相似,那它們的區(qū)別在哪里呢 ?

可以發(fā)現(xiàn):

歸并排序的處理過程是由下而上的,先處理子問題,然后再合并。

而快排正好相反,它的處理過程是由上而下的,先分區(qū),然后再處理子問題。

歸并排序雖然是穩(wěn)定的、時(shí)間復(fù)雜度為 O(nlogn) 的排序算法,但是它是非原地排序算法。

歸并之所以是非原地排序算法,主要原因是合并函數(shù)無法在原地執(zhí)行。

快速排序通過設(shè)計(jì)巧妙的原地分區(qū)函數(shù),可以實(shí)現(xiàn)原地排序,解決了歸并排序占用太多內(nèi)存的問題。

4. 希爾排序(Shell Sort)

思想

先將整個(gè)待排序的記錄序列分割成為若干子序列。

分別進(jìn)行直接插入排序。

待整個(gè)序列中的記錄基本有序時(shí),再對全體記錄進(jìn)行依次直接插入排序。

過程

舉個(gè)易于理解的例子:[35, 33, 42, 10, 14, 19, 27, 44],我們采取間隔 4。創(chuàng)建一個(gè)位于 4 個(gè)位置間隔的所有值的虛擬子列表。下面這些值是 { 35, 14 },{ 33, 19 },{ 42, 27 } 和 { 10, 44 }。

我們比較每個(gè)子列表中的值,并在原始數(shù)組中交換它們(如果需要)。完成此步驟后,新數(shù)組應(yīng)如下所示。

然后,我們采用 2 的間隔,這個(gè)間隙產(chǎn)生兩個(gè)子列表:{ 14, 27, 35, 42 }, { 19, 10, 33, 44 }。

我們比較并交換原始數(shù)組中的值(如果需要)。完成此步驟后,數(shù)組變成:[14, 10, 27, 19, 35, 33, 42, 44],圖如下所示,10 與 19 的位置互換一下。

最后,我們使用值間隔 1 對數(shù)組的其余部分進(jìn)行排序,Shell sort 使用插入排序?qū)?shù)組進(jìn)行排序。

實(shí)現(xiàn)

const shellSort = arr => {
    let len = arr.length,
        temp,
        gap = 1;
    console.time("希爾排序耗時(shí)");
    while (gap < len / 3) {
        //動態(tài)定義間隔序列
        gap = gap * 3 + 1;
    }
    for (gap; gap > 0; gap = Math.floor(gap / 3)) {
        for (let i = gap; i < len; i++) {
            temp = arr[i];
            let j = i - gap;
            for (; j >= 0 && arr[j] > temp; j -= gap) {
                arr[j + gap] = arr[j];
            }
            arr[j + gap] = temp;
            console.log("arr  :", arr);
        }
    }
    console.timeEnd("希爾排序耗時(shí)");
    return arr;
};

測試

// 測試
const array = [35, 33, 42, 10, 14, 19, 27, 44];
console.log("原始array:", array);
const newArr = shellSort(array);
console.log("newArr:", newArr);
// 原始 array: ??[35, 33, 42, 10, 14, 19, 27, 44]
// arr      : ??[14, 33, 42, 10, 35, 19, 27, 44]
// arr      : ??[14, 19, 42, 10, 35, 33, 27, 44]
// arr      : ??[14, 19, 27, 10, 35, 33, 42, 44]
// arr      : ??[14, 19, 27, 10, 35, 33, 42, 44]
// arr      : ??[14, 19, 27, 10, 35, 33, 42, 44]
// arr      : ??[14, 19, 27, 10, 35, 33, 42, 44]
// arr      : ??[10, 14, 19, 27, 35, 33, 42, 44]
// arr      : ??[10, 14, 19, 27, 35, 33, 42, 44]
// arr      : ??[10, 14, 19, 27, 33, 35, 42, 44]
// arr      : ??[10, 14, 19, 27, 33, 35, 42, 44]
// arr      : ??[10, 14, 19, 27, 33, 35, 42, 44]
// 希爾排序耗時(shí): 3.592041015625ms
// newArr: ?   [10, 14, 19, 27, 33, 35, 42, 44]

分析

第一,希爾排序是原地排序算法嗎 ?

希爾排序過程中,只涉及相鄰數(shù)據(jù)的交換操作,只需要常量級的臨時(shí)空間,空間復(fù)雜度為 O(1) 。所以,希爾排序是原地排序算法。

第二,希爾排序是穩(wěn)定的排序算法嗎 ?

我們知道,單次直接插入排序是穩(wěn)定的,它不會改變相同元素之間的相對順序,但在多次不同的插入排序過程中,相同的元素可能在各自的插入排序中移動,可能導(dǎo)致相同元素相對順序發(fā)生變化。
因此,希爾排序不穩(wěn)定

第三,希爾排序的時(shí)間復(fù)雜度是多少 ?

最佳情況:T(n) = O(n logn)。
最差情況:T(n) = O(n (log(n))2)。
平均情況:T(n) = 取決于間隙序列。

動畫

5. 堆排序(Heap Sort)

堆的定義

堆其實(shí)是一種特殊的樹。只要滿足這兩點(diǎn),它就是一個(gè)堆。

堆是一個(gè)完全二叉樹。

完全二叉樹:除了最后一層,其他層的節(jié)點(diǎn)個(gè)數(shù)都是滿的,最后一層的節(jié)點(diǎn)都靠左排列。

堆中每一個(gè)節(jié)點(diǎn)的值都必須大于等于(或小于等于)其子樹中每個(gè)節(jié)點(diǎn)的值。

也可以說:堆中每個(gè)節(jié)點(diǎn)的值都大于等于(或者小于等于)其左右子節(jié)點(diǎn)的值。這兩種表述是等價(jià)的。

對于每個(gè)節(jié)點(diǎn)的值都大于等于子樹中每個(gè)節(jié)點(diǎn)值的堆,我們叫作大頂堆
對于每個(gè)節(jié)點(diǎn)的值都小于等于子樹中每個(gè)節(jié)點(diǎn)值的堆,我們叫作小頂堆

其中圖 1 和 圖 2 是大頂堆,圖 3 是小頂堆,圖 4 不是堆。除此之外,從圖中還可以看出來,對于同一組數(shù)據(jù),我們可以構(gòu)建多種不同形態(tài)的堆。

思想

將初始待排序關(guān)鍵字序列 (R1, R2 .... Rn) 構(gòu)建成大頂堆,此堆為初始的無序區(qū);

將堆頂元素 R[1] 與最后一個(gè)元素 R[n] 交換,此時(shí)得到新的無序區(qū) (R1, R2, ..... Rn-1) 和新的有序區(qū) (Rn) ,且滿足 R[1, 2 ... n-1] <= R[n]。

由于交換后新的堆頂 R[1] 可能違反堆的性質(zhì),因此需要對當(dāng)前無序區(qū) (R1, R2 ...... Rn-1) 調(diào)整為新堆,然后再次將 R[1] 與無序區(qū)最后一個(gè)元素交換,得到新的無序區(qū) (R1, R2 .... Rn-2) 和新的有序區(qū) (Rn-1, Rn)。不斷重復(fù)此過程,直到有序區(qū)的元素個(gè)數(shù)為 n - 1,則整個(gè)排序過程完成。

實(shí)現(xiàn)

// 堆排序
const heapSort = array => {
    console.time("堆排序耗時(shí)");
    // 初始化大頂堆,從第一個(gè)非葉子結(jié)點(diǎn)開始
    for (let i = Math.floor(array.length / 2 - 1); i >= 0; i--) {
        heapify(array, i, array.length);
    }
    // 排序,每一次 for 循環(huán)找出一個(gè)當(dāng)前最大值,數(shù)組長度減一
    for (let i = Math.floor(array.length - 1); i > 0; i--) {
        // 根節(jié)點(diǎn)與最后一個(gè)節(jié)點(diǎn)交換
        swap(array, 0, i);
        // 從根節(jié)點(diǎn)開始調(diào)整,并且最后一個(gè)結(jié)點(diǎn)已經(jīng)為當(dāng)前最大值,不需要再參與比較,所以第三個(gè)參數(shù)為 i,即比較到最后一個(gè)結(jié)點(diǎn)前一個(gè)即可
        heapify(array, 0, i);
    }
    console.timeEnd("堆排序耗時(shí)");
    return array;
};

// 交換兩個(gè)節(jié)點(diǎn)
const swap = (array, i, j) => {
    let temp = array[i];
    array[i] = array[j];
    array[j] = temp;
};

// 將 i 結(jié)點(diǎn)以下的堆整理為大頂堆,注意這一步實(shí)現(xiàn)的基礎(chǔ)實(shí)際上是:
// 假設(shè)結(jié)點(diǎn) i 以下的子堆已經(jīng)是一個(gè)大頂堆,heapify 函數(shù)實(shí)現(xiàn)的
// 功能是實(shí)際上是:找到 結(jié)點(diǎn) i 在包括結(jié)點(diǎn) i 的堆中的正確位置。
// 后面將寫一個(gè) for 循環(huán),從第一個(gè)非葉子結(jié)點(diǎn)開始,對每一個(gè)非葉子結(jié)點(diǎn)
// 都執(zhí)行 heapify 操作,所以就滿足了結(jié)點(diǎn) i 以下的子堆已經(jīng)是一大頂堆
const heapify = (array, i, length) => {
    let temp = array[i]; // 當(dāng)前父節(jié)點(diǎn)
    // j < length 的目的是對結(jié)點(diǎn) i 以下的結(jié)點(diǎn)全部做順序調(diào)整
    for (let j = 2 * i + 1; j < length; j = 2 * j + 1) {
        temp = array[i]; // 將 array[i] 取出,整個(gè)過程相當(dāng)于找到 array[i] 應(yīng)處于的位置
        if (j + 1 < length && array[j] < array[j + 1]) {
            j++; // 找到兩個(gè)孩子中較大的一個(gè),再與父節(jié)點(diǎn)比較
        }
        if (temp < array[j]) {
            swap(array, i, j); // 如果父節(jié)點(diǎn)小于子節(jié)點(diǎn):交換;否則跳出
            i = j; // 交換后,temp 的下標(biāo)變?yōu)?j
        } else {
            break;
        }
    }
};

測試

const array = [4, 6, 8, 5, 9, 1, 2, 5, 3, 2];
console.log("原始array:", array);
const newArr = heapSort(array);
console.log("newArr:", newArr);
// 原始 array: ?[4, 6, 8, 5, 9, 1, 2, 5, 3, 2]
// 堆排序耗時(shí): 0.15087890625ms
// newArr: ?   [1, 2, 2, 3, 4, 5, 5, 6, 8, 9]

分析

第一,堆排序是原地排序算法嗎 ?

整個(gè)堆排序的過程,都只需要極個(gè)別臨時(shí)存儲空間,所以堆排序是原地排序算法。

第二,堆排序是穩(wěn)定的排序算法嗎 ?

因?yàn)樵谂判虻倪^程,存在將堆的最后一個(gè)節(jié)點(diǎn)跟堆頂節(jié)點(diǎn)互換的操作,所以就有可能改變值相同數(shù)據(jù)的原始相對順序。
所以,堆排序是不穩(wěn)定的排序算法。

第三,堆排序的時(shí)間復(fù)雜度是多少 ?

堆排序包括建堆和排序兩個(gè)操作,建堆過程的時(shí)間復(fù)雜度是 O(n),排序過程的時(shí)間復(fù)雜度是 O(nlogn),所以,堆排序整體的時(shí)間復(fù)雜度是 O(nlogn)。
最佳情況:T(n) = O(nlogn)。
最差情況:T(n) = O(nlogn)。
平均情況:T(n) = O(nlogn)。

動畫

6. 排序算法的復(fù)雜性對比

復(fù)雜性對比

算法可視化工具

算法可視化工具 algorithm-visualizer
算法可視化工具 algorithm-visualizer 是一個(gè)交互式的在線平臺,可以從代碼中可視化算法,還可以看到代碼執(zhí)行的過程。

效果如下圖。

旨在通過交互式可視化的執(zhí)行來揭示算法背后的機(jī)制。

算法可視化來源 https://visualgo.net/en

效果如下圖。

https://www.ee.ryerson.ca

illustrated-algorithms

變量和操作的可視化表示增強(qiáng)了控制流和實(shí)際源代碼。您可以快速前進(jìn)和后退執(zhí)行,以密切觀察算法的工作方式。

7. 文章輸出計(jì)劃

JavaScript 數(shù)據(jù)結(jié)構(gòu)與算法之美 的系列文章,堅(jiān)持 3 - 7 天左右更新一篇,暫定計(jì)劃如下表。

| 標(biāo)題 | 鏈接 |
| :------ | :------ |
| 時(shí)間和空間復(fù)雜度 | https://github.com/biaochenxu... |
| 線性表(數(shù)組、鏈表、棧、隊(duì)列) | https://github.com/biaochenxu... |
| 實(shí)現(xiàn)一個(gè)前端路由,如何實(shí)現(xiàn)瀏覽器的前進(jìn)與后退 ?| https://github.com/biaochenxu... |
| 棧內(nèi)存與堆內(nèi)存 、淺拷貝與深拷貝 | https://github.com/biaochenxu... |
| 遞歸 | https://github.com/biaochenxu... |
| 非線性表(樹、堆) | https://github.com/biaochenxu... |
| 冒泡排序、選擇排序、插入排序 | https://github.com/biaochenxu... |
| 歸并排序、快速排序、希爾排序、堆排序 | https://github.com/biaochenxu... |
| 計(jì)數(shù)排序、桶排序、基數(shù)排序 | 精彩待續(xù) |
| 十大經(jīng)典排序匯總 | 精彩待續(xù) |
| 強(qiáng)烈推薦 GitHub 上值得前端學(xué)習(xí)的數(shù)據(jù)結(jié)構(gòu)與算法項(xiàng)目 | https://github.com/biaochenxu... |

如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤剑垊?wù)必給予指正,十分感謝。
8. 最后

文中所有的代碼及測試事例都已經(jīng)放到我的 GitHub 上了。

覺得有用 ?喜歡就收藏,順便點(diǎn)個(gè)贊吧。

參考文章:

JS 實(shí)現(xiàn)堆排序

數(shù)據(jù)結(jié)構(gòu)與算法之美

十大經(jīng)典排序算法總結(jié)(JavaScript 描述)

JS 中可能用得到的全部的排序算法

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/106010.html

相關(guān)文章

  • JavaScript 數(shù)據(jù)結(jié)構(gòu)算法之美 - 十大經(jīng)典排序算法匯總

    摘要:筆者寫的數(shù)據(jù)結(jié)構(gòu)與算法之美系列用的語言是,旨在入門數(shù)據(jù)結(jié)構(gòu)與算法和方便以后復(fù)習(xí)。這應(yīng)該是目前較為簡單的十大經(jīng)典排序算法的文章講解了吧。比如原本在的前面,而,排序之后,在的后面十大經(jīng)典排序算法冒泡排序思想冒泡排序只會操作相鄰的兩個(gè)數(shù)據(jù)。 showImg(https://segmentfault.com/img/bVbvHet); 1. 前言 算法為王。想學(xué)好前端,先練好內(nèi)功,內(nèi)功不行,就...

    zsy888 評論0 收藏0
  • JavaScript 數(shù)據(jù)結(jié)構(gòu)算法之美 - 冒泡排序、插入排序、選擇排序

    摘要:之所以把冒泡排序選擇排序插入排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。其中,冒泡排序就是原地排序算法。所以冒泡排序是穩(wěn)定的排序算法。選擇排序思路選擇排序算法的實(shí)現(xiàn)思路有點(diǎn)類似插入排序,也分已排序區(qū)間和未排序區(qū)間。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 1. 前言 算法為王。 想學(xué)好前端,先練好內(nèi)功,...

    canger 評論0 收藏0
  • 優(yōu)秀程序員都應(yīng)該學(xué)習(xí)的 GitHub 上開源的數(shù)據(jù)結(jié)構(gòu)算法項(xiàng)目

    摘要:強(qiáng)烈推薦上值得前端學(xué)習(xí)的數(shù)據(jù)結(jié)構(gòu)與算法項(xiàng)目,包含圖的演示過程與視頻講解。該倉庫包含了多種基于的算法與數(shù)據(jù)結(jié)構(gòu),提供進(jìn)一步閱讀的解釋和鏈接。數(shù)據(jù)結(jié)構(gòu)和算法必知必會的個(gè)代碼實(shí)現(xiàn)。 showImg(https://segmentfault.com/img/bVbvpYZ); 前言 算法為王。想學(xué)好前端,先練好內(nèi)功,內(nèi)功不行,就算招式練的再花哨,終究成不了高手;只有內(nèi)功深厚者,前端之路才會走得...

    cheukyin 評論0 收藏0
  • JavaScript 數(shù)據(jù)結(jié)構(gòu)算法之美 - 桶排序、計(jì)數(shù)排序、基數(shù)排序

    摘要:之所以把計(jì)數(shù)排序桶排序基數(shù)排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。動畫計(jì)數(shù)排序思想找出待排序的數(shù)組中最大和最小的元素。桶排序計(jì)數(shù)排序能派上用場嗎手機(jī)號碼有位,范圍太大,顯然不適合用這兩種排序算法。 showImg(https://segmentfault.com/img/bVbuF9e?w=900&h=500); 1. 前言 算法為王。 想學(xué)好前端,先練好內(nèi)功,只有內(nèi)功深厚者...

    Awbeci 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<