js--js實現基礎排序演演算法

2022-06-30 15:05:54

前言

  文字來總結常見的排序演演算法,通過 JvavScript  來實現

正文

  1、氣泡排序

  演演算法思想:比較相鄰兩個元素的大小,如果第一個比第二個大,就交換它們。從頭遍歷到尾部,當一輪遍歷完後,陣列最後一個元素是最大的。除去最後一個元素,對剩下的元素重複執行上面的流程,每次找出剩餘元素中最大的,遍歷完後,陣列是升序的

  演演算法分析:總共需要進行length * (length - 1) / 2 次比較,所以時間複雜度為O(n^2),因為只需要有一個存放常數的空間,元素本身在原陣列上進行交換,所以空間複雜度為O(1)

        function bubbleSort(array) {
            if (!Array.isArray(array)) {
                throw new Error('引數必須為陣列');
                return;
            }
            var n = 0, m = 0 // n表示趟數,m表示比較次數
            for (let i = array.length - 1; i > 0; i--) { // 外層for表示遍歷的趟數
                for (let j = 0; j < i; j++) { // 內層for表示每趟需要比較的 j 和 j+1 對應的數
                    if (arr[j] > arr[j + 1]) {
                        [arr[j + 1], arr[j]] = [arr[j], arr[j + 1]]
                    }
                    m++
                }
                n++
            }
            console.log("遍歷趟數" + n, "比較次數" + m);//遍歷趟數8 比較次數36
            return array
        }
        var arr = [7, 3, 6, 9, 24, 0, 1, 45, 8]
        console.log(bubbleSort(arr)); //[0, 1, 3, 6, 7, 8, 9, 24, 45]

  我們在每一輪迴圈中,可以記住最後一次交換的元素,這之後的元素就肯定是已經排完序的,這樣可以減少總的迴圈次數

        function bubbleSort2(array) {
            if (!Array.isArray(array)) {
                throw new Error('引數必須為陣列');
                return;
            }
            var n = 0, m = 0 // n表示趟數,m表示比較次數
            for (var i = array.length - 1; i > 0;) { // 用來表示遍歷 n-1 趟
                var cursor = 0;  // 用來記錄本輪最後一次交換的元素位置
                for (var j = 0; j < i; j++) {
                    if (array[j] > array[j + 1]) {
                        cursor = j;
                        [arr[j + 1], arr[j]] = [arr[j], arr[j + 1]]
                    }
                    m++
                }
                n++
                i = cursor;
                
            }
            console.log("遍歷趟數" + n, "比較次數" + m);//遍歷趟數6 比較次數29
            return array
        }
        var arr = [7, 3, 6, 9, 24, 0, 1, 45, 8]
        console.log(bubbleSort2(arr)); //[0, 1, 3, 6, 7, 8, 9, 24, 45]

   2、選擇排序

  實現思路
        (1)從頭遍歷到尾部,找出所有項中最大的一個元素
        (2)將這個元素和第一個元素交換
        (3)對剩下的元素重複進行上面的操作,每次找出剩餘中最大的最後的陣列是降序排列的
        (4) 演演算法分析
  總共需要進行length * (length - 1) / 2 次比較,所以時間複雜度為O(n^2),因為只需要有兩個存放常     量的空間,元素本身在原陣列上進行交換,所以空間複雜度為O(1)
 
        function selectSort(array) {
            if (!Array.isArray(array)) {
                throw new Error('引數必須為陣列');
                return;
            }
            for (let i = 0; i < array.length; i++) {
                var maxIndex = i, maxValue = array[i] // 設定i為最大元素下標
                // 找出剩下元素中的最大值,第一次迴圈找出最大值
                for (let j = i + 1; j < array.length; j++) {
                    if (array[j] > maxValue) {
                        maxIndex = j
                        maxValue = array[j]
                    }
                }
                // 如果剩下的元素中最大值下標大於i則發生交換
                if (maxIndex > i) {
                    [array[i], array[maxIndex]] = [array[maxIndex], array[i]]
                }
            }
            return array
        }
        var arr = [7, 3, 6, 9, 24, 0, 1, 45, 8]
        console.log(selectSort(arr)); //[45, 24, 9, 8, 7, 6, 3, 1, 0]

   3、插入排序

  實現思路

  (1)將陣列前面部分看做有序陣列

  (2)每次將後面部分的第一個與已排序陣列作比較,插入到合適的位置

  (3)有序陣列初始狀態有1個數位

  (4)演演算法分析

  (5)時間複雜度為O(n^2)

        function insertSort(array) {
            if (!Array.isArray(array)) {
                throw new Error('引數必須為陣列');
                return;
            }
            for (var i = 1; i < array.length; i++) {
                var temp = array[i] //當前值
                for (var j = i; j > 0 && temp < array[j - 1]; j--) {
                    // 當前值和之前的每個值進行比較,發現有比當前值小的值就進行重新賦值
                    array[j] = array[j - 1];
                }
                array[j] = temp;
            }
            return array;
        }
        var arr = [7, 3, 6, 9, 24, 0, 1, 45, 8]
        console.log(insertSort(arr)); //[45, 24, 9, 8, 7, 6, 3, 1, 0]

  4、快速排序:

  演演算法思想:將陣列的第一個數位作為基準,最後使得基準數位位於陣列中間某個位置,它的左邊的數位都比它小,它的右邊的數位都比它大。

  演演算法實現:設定兩個分別指向陣列頭部和尾部的指標i和j,首先向左移動j,使得array[j] 小於基準。然後向右移動i,使得array[i] 大於基準,交換這兩個元素。當i 和j 的值相等時,交換基準與位置i上的元素,然後對i左邊以及右邊的元素分別進行快速排序。

        function quickSort(array) {
            const sort = function (arr, left = 0, right = arr.length - 1) {
                if (left >= right) {// 遞迴退出條件
                    return
                }
                let i = left, j = right // 定義兩個指標
                let pivot = arr[i] // 定義基準資料

                while (i < j) { // 把所有比基準數
                    while (j > i && arr[j] >= pivot) { //找到一個比基準值小的數位置為j
                        j--
                    }
                    arr[i] = arr[j] // 將j的值給了i位置的元素,此時j位置還是原來的數
                    while (i < j && arr[i] < pivot) {
                        i++
                    }
                    arr[j] = arr[i] // 將i位置的值給了j位置的元素,此時i的位置還是原來的數
                }
                // 本次交換完畢,此時ij兩個指標重合,把基準值賦值給i即可
                arr[i] = pivot
                sort(arr, left, j - 1) // 將左邊的無序陣列重複上面的操作
                sort(arr, j + 1, right) // 將右邊的無序陣列重複上面的操作
            }
            const newArr = array.concat() // 為了保證這個函數是純函數拷貝一次陣列
            sort(newArr)
            return newArr
        }
        var arr = [7, 3, 6, 9, 24, 0, 1, 45, 8]
        console.log(quickSort(arr)); //[0, 1, 3, 6, 7, 8, 9, 24, 45]

 寫在最後

  以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長之路會持續更新一些工作中常見的問題和技術點。