欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解JavaScript如何實(shí)現(xiàn)四種常用排序

 更新時(shí)間:2022年02月26日 15:10:00   作者:果凍OoO  
這篇文章主要為大家介紹了如何利用JavaScript實(shí)現(xiàn)四個(gè)常用的排序:插入排序、交換排序、選擇排序和歸并排序,文中利用動(dòng)圖詳細(xì)介紹了實(shí)現(xiàn)過程,需要的可以參考一下

一、插入排序

插入排序有直接插入排序,折半插入排序,希爾排序,這里只實(shí)現(xiàn)常用的直接插入排序

直接插入排序

將左側(cè)序列看成一個(gè)有序序列,每次將一個(gè)數(shù)字插入該有序序列。

插入時(shí),從有序序列最右側(cè)開始比較,若比較的數(shù)較大,后移一位。

function insertSort(array) {
//第一個(gè)默認(rèn)已經(jīng)排好
      for (let i = 1; i < array.length; i++) {
        let target = i;
        for (let j = i - 1; j >= 0; j--) {
          if (array[target] < array[j]) {
            [array[target], array[j]] = [array[j], array[target]]
            target = j;
          } else {
            break;
          }
        }
      }
      return array;
    }

復(fù)雜度

時(shí)間復(fù)雜度:O(n2)

空間復(fù)雜度:O(1)

穩(wěn)定性

穩(wěn)定

二、交換排序

(1)冒泡排序

循環(huán)數(shù)組,比較當(dāng)前元素和上一個(gè)元素,如果當(dāng)前元素比上一個(gè)元素小,向下冒泡。

這樣一次循環(huán)之后最前一個(gè)數(shù)就是本數(shù)組最小的數(shù)。

下一次循環(huán)繼續(xù)上面的操作,不循環(huán)已經(jīng)排序好的數(shù)。

優(yōu)化:當(dāng)一次循環(huán)沒有發(fā)生冒泡,說明已經(jīng)排序完成,停止循環(huán)。

    function bubbleSort(array) {
        //第一個(gè)循環(huán)是所需次數(shù)
      for (let j = 0; j < array.length; j++) {
        let complete = true;
        for (let i = array.length-1; i>j; i--) {
          // 比較相鄰數(shù)
          if (array[i] < array[i -1]) {
            [array[i], array[i - 1]] = [array[i - 1], array[i]];
            complete = false;
          }
        }
        // 沒有冒泡結(jié)束循環(huán)
        if (complete) {
          break;
        }
      }
      return array;
    }

復(fù)雜度

時(shí)間復(fù)雜度:O(n2)

空間復(fù)雜度:O(1)

穩(wěn)定性

穩(wěn)定

(2)快速排序

快速排序:通過一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一部分的所有數(shù)據(jù)比另一部分的所有數(shù)據(jù)要小,再按這種方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,整個(gè)排序過程可以遞歸進(jìn)行,使整個(gè)數(shù)據(jù)變成有序序列。

實(shí)現(xiàn)步驟:

  • 選擇一個(gè)基準(zhǔn)元素target(一般選擇第一個(gè)數(shù))
  • 將比target小的元素移動(dòng)到數(shù)組左邊,比target大的元素移動(dòng)到數(shù)組右邊
  • 分別對(duì)target左側(cè)和右側(cè)的元素進(jìn)行快速排序

從上面的步驟中我們可以看出,快速排序也利用了分治的思想(將問題分解成一些小問題遞歸求解)

下面是對(duì)序列6、1、2、7、9、3、4、5、10、8排序的過程:

//JS自帶的sort()就是快排
function quickSort(array, start, end) {
      if (end - start < 1) {
        return;
      }
      const target = array[start];
      let l = start;
      let r = end;
      while (l < r) {
        while (l < r && array[r] >= target) {
          r--;
        }
        array[l] = array[r];
        while (l < r && array[l] < target) {
          l++;
        }
        array[r] = array[l];
      }
      array[l] = target;
      quickSort(array, start, l - 1);
      quickSort(array, l + 1, end);
      return array;
    }

復(fù)雜度

時(shí)間復(fù)雜度:平均O(nlogn),最壞O(n2),實(shí)際上大多數(shù)情況下小于O(nlogn)

空間復(fù)雜度:O(logn)(遞歸調(diào)用消耗)

穩(wěn)定性

不穩(wěn)定

三、選擇排序

(1)簡(jiǎn)單選擇排序

每次循環(huán)選取一個(gè)最小的數(shù)字放到前面的有序序列中。 

 function selectionSort(array) {
      for (let i = 0; i < array.length - 1; i++) {
        let minIndex = i;
        for (let j = i + 1; j < array.length; j++) {
          if (array[j] < array[minIndex]) {
            minIndex = j;
          }
        }
        [array[minIndex], array[i]] = [array[i], array[minIndex]];
      }
    }

復(fù)雜度

時(shí)間復(fù)雜度:O(n2)

空間復(fù)雜度:O(1)

穩(wěn)定性

不穩(wěn)定

(2)堆排序

創(chuàng)建一個(gè)大頂堆,大頂堆的堆頂一定是最大的元素。

交換第一個(gè)元素和最后一個(gè)元素,讓剩余的元素繼續(xù)調(diào)整為大頂堆。

從后往前以此和第一個(gè)元素交換并重新構(gòu)建,排序完成。

 function heapSort(array) {
      creatHeap(array);
      console.log(array);
      // 交換第一個(gè)和最后一個(gè)元素,然后重新調(diào)整大頂堆
      for (let i = array.length - 1; i > 0; i--) {
        [array[i], array[0]] = [array[0], array[i]];
        adjust(array, 0, i);
      }
      return array;
    }
    // 構(gòu)建大頂堆,從第一個(gè)非葉子節(jié)點(diǎn)開始,進(jìn)行下沉操作
    function creatHeap(array) {
      const len = array.length;
      const start = parseInt(len / 2) - 1;
      for (let i = start; i >= 0; i--) {
        adjust(array, i, len);
      }
    }
    // 將第target個(gè)元素進(jìn)行下沉,孩子節(jié)點(diǎn)有比他大的就下沉
    function adjust(array, target, len) {
      for (let i = 2 * target + 1; i < len; i = 2 * i + 1) {
        // 找到孩子節(jié)點(diǎn)中最大的
        if (i + 1 < len && array[i + 1] > array[i]) {
          i = i + 1;
        }
        // 下沉
        if (array[i] > array[target]) {
          [array[i], array[target]] = [array[target], array[i]]
          target = i;
        } else {
          break;
        }
      }
    }

復(fù)雜度

時(shí)間復(fù)雜度:O(nlogn)

空間復(fù)雜度:O(1)

穩(wěn)定性

不穩(wěn)定

四、歸并排序

利用歸并的思想實(shí)現(xiàn)的排序方法。

該算法是采用分治法(Divide and Conquer)的一個(gè)非常典型的應(yīng)用。(分治法將問題分成一些小的問題然后遞歸求解,而治的階段則將分的階段得到的各答案"修補(bǔ)"在一起,即分而治之)。

  • 將已有序的子序列合并,得到完全有序的序列
  • 即先使每個(gè)子序列有序,再使子序列段間有序
  • 若將兩個(gè)有序表合并成一個(gè)有序表,稱為二路歸并

分割:

  • 將數(shù)組從中點(diǎn)進(jìn)行分割,分為左、右兩個(gè)數(shù)組
  • 遞歸分割左、右數(shù)組,直到數(shù)組長(zhǎng)度小于2

歸并:

如果需要合并,那么左右兩數(shù)組已經(jīng)有序了。

創(chuàng)建一個(gè)臨時(shí)存儲(chǔ)數(shù)組temp,比較兩數(shù)組第一個(gè)元素,將較小的元素加入臨時(shí)數(shù)組

若左右數(shù)組有一個(gè)為空,那么此時(shí)另一個(gè)數(shù)組一定大于temp中的所有元素,直接將其所有元素加入temp 

function mergeSort(array) {
      if (array.length < 2) {
        return array;
      }
      const mid = Math.floor(array.length / 2);
      const front = array.slice(0, mid);
      const end = array.slice(mid);
      return merge(mergeSort(front), mergeSort(end));
    }
 
    function merge(front, end) {
      const temp = [];
      while (front.length && end.length) {
        if (front[0] < end[0]) {
          temp.push(front.shift());
        } else {
          temp.push(end.shift());
        }
      }
      while (front.length) {
        temp.push(front.shift());
      }
      while (end.length) {
        temp.push(end.shift());
      }
      return temp;
    }

做題時(shí),上面多了刪除過程,特別大的例子,時(shí)間也可能會(huì)超,用下面的方法

function merge(left, right){
    let leftLen = left.length, rightLen = right.length;
    let i = 0, j = 0;
    let temp = new Array(leftLen + rightLen);
    for(let cur = 0; cur < leftLen + rightLen; cur++){
        // 檢查i, j有沒有超界
        if(i >= leftLen) temp[cur]= right[j++];
        else if(j >= rightLen) temp[cur] = left[i++];
        else if(left[i] <= right[j]){
            temp[cur] = left[i++];
        }else{
            temp[cur] = right[j++];
        }
    }
    return temp;
}

復(fù)雜度

時(shí)間復(fù)雜度:O(nlogn)

空間復(fù)雜度:O(n)

穩(wěn)定性

穩(wěn)定

到此這篇關(guān)于詳解JavaScript如何實(shí)現(xiàn)四種常用排序的文章就介紹到這了,更多相關(guān)JavaScript排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js+canvas實(shí)現(xiàn)兩張圖片合并成一張圖片的方法

    js+canvas實(shí)現(xiàn)兩張圖片合并成一張圖片的方法

    這篇文章主要介紹了js+canvas實(shí)現(xiàn)兩張圖片合并成一張圖片的方法,結(jié)合實(shí)例形式分析了JavaScript結(jié)合HTML5 canvas實(shí)現(xiàn)圖片合并的操作技巧,并附帶了Java圖片合并的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2019-11-11
  • js常用代碼段整理

    js常用代碼段整理

    以下是平時(shí)收集的幾個(gè)常用代碼段,大多數(shù)是從網(wǎng)上搜集而來。也均為未找到是誰誰原創(chuàng),是否允許轉(zhuǎn)載等要求, 所以如果看到的朋友發(fā)現(xiàn)其中有些代碼是自己寫的,還請(qǐng)?jiān)徳谙罗D(zhuǎn)帖出來
    2011-11-11
  • D3.js入門之D3?DataJoin的使用

    D3.js入門之D3?DataJoin的使用

    DataJoin(數(shù)據(jù)連接)是D3中很重要的一個(gè)概念。D3是基于數(shù)據(jù)操作DOM的js庫,DataJoin使我們能夠根據(jù)現(xiàn)有?HTML?文檔中的數(shù)據(jù)集注入、修改和刪除元素。本文主要和大家詳細(xì)聊聊DataJoin的使用,感興趣的可以學(xué)習(xí)一下
    2022-11-11
  • 淺析ES6的八進(jìn)制與二進(jìn)制整數(shù)字面量

    淺析ES6的八進(jìn)制與二進(jìn)制整數(shù)字面量

    這篇文章給大家介紹了ES6特性中的八進(jìn)制和二進(jìn)制整數(shù)字面量,介紹的挺不錯(cuò)的現(xiàn)在分享給大家,有需要的可以參考借鑒。
    2016-08-08
  • electron實(shí)現(xiàn)qq快捷登錄的方法示例

    electron實(shí)現(xiàn)qq快捷登錄的方法示例

    這篇文章主要介紹了electron實(shí)現(xiàn)qq快捷登錄的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-10-10
  • JavaScript JSON數(shù)據(jù)處理全集(小結(jié))

    JavaScript JSON數(shù)據(jù)處理全集(小結(jié))

    這篇文章主要介紹了JavaScript JSON數(shù)據(jù)處理全集,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • JS創(chuàng)建Tag標(biāo)簽的方法詳解

    JS創(chuàng)建Tag標(biāo)簽的方法詳解

    這篇文章主要介紹了JS創(chuàng)建Tag標(biāo)簽的方法,結(jié)合具體實(shí)例形式分析了javascript動(dòng)態(tài)操作頁面HTML元素實(shí)現(xiàn)tag標(biāo)簽功能的步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • js點(diǎn)擊選擇文本的方法

    js點(diǎn)擊選擇文本的方法

    這篇文章主要介紹了js點(diǎn)擊選擇文本的方法,涉及針對(duì)html節(jié)點(diǎn)的操作與選中技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-02-02
  • js實(shí)現(xiàn)文章文字大小字號(hào)功能完整實(shí)例

    js實(shí)現(xiàn)文章文字大小字號(hào)功能完整實(shí)例

    這篇文章主要介紹了js實(shí)現(xiàn)文章文字大小字號(hào)功能的實(shí)現(xiàn)方法,可根據(jù)用戶習(xí)慣調(diào)整顯示文字的大小.詳細(xì)講述了實(shí)現(xiàn)這一功能的完整步驟.是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-11-11
  • JS使用正則表達(dá)式過濾多個(gè)詞語并替換為相同長(zhǎng)度星號(hào)的方法

    JS使用正則表達(dá)式過濾多個(gè)詞語并替換為相同長(zhǎng)度星號(hào)的方法

    這篇文章主要介紹了JS使用正則表達(dá)式過濾多個(gè)詞語并替換為相同長(zhǎng)度星號(hào)的方法,涉及javascript字符串與正則替換操作相關(guān)技巧,需要的朋友可以參考下
    2016-08-08

最新評(píng)論