JavaScript 排序演算法(JavaScript sorting algorithms)

来源:http://www.cnblogs.com/givebest/archive/2017/08/13/7355161.html
-Advertisement-
Play Games

介紹常見的排序演算法:冒泡排序、選擇排序、插入排序、歸併排序、快速排序及簡單的性能測試。 ...


JavaScrip 排序演算法(JavaScript Sorting Algorithms)

基礎構造函數

以下幾種排序演算法做為方法放在構造函數里。

function ArrayList () {
  var array = [];

  // 交換位置
  var swap = function (index1, index2) {
    var aux = array[index1];
    array[index1] = array[index2];
    array[index2] = aux;
  }

  this.insert = function (item) {
    array.push(item);
  };

  this.toString = function () {
    return array.join();
  };

  this.val = function () {
    return array;
  }

  // 冒泡排序
  this.bubbleSort = function () {
    //etc
  }
}

1. 冒泡排序

冒泡排序比較任何兩個相鄰的項,如果第一個比第二個大,則交換它們。

複雜度 O(n^2)。

代碼

this.bubbleSort = function () {
  console.time('Bubble Sort');
  var length = array.length;
  for (var i = 0; i < length; i++) {
    for (var j = 0; j < length - 1 - i; j++) {
      if (array[j] > array[j+1]) {
        swap(j, j + 1);
      }
    }
  }
  console.timeEnd('Bubble Sort');
}

圖解

冒泡排序

2. 選擇排序

選擇排序演算法是一種原址比較排序演算法。選擇排序大致的思路是找到數據結構中的最小值並將其放置在第一位,接著找到第二小的值並將其放在第二位,以此類推。

複雜度:O(n^2)。

代碼

this.selectionSort = function () {
  console.time('selectionSort');
  var length = array.length,
      indexMin;

  for (var i = 0; i < length - 1; i++) {
    indexMin = i;
    for (var j = i; j < length; j++) {
      if (array[indexMin] > array[j]) {
        indexMin = j;
      }
    }

    if (i !== indexMin) {
      swap(i, indexMin);
    }
  }
  console.timeEnd('selectionSort');
}

圖解

選擇排序

3. 插入排序

插入排序每次排一個數組項,以此方式構建最後的排序數組。假定第一項已經排序了,接著,它和第二項進行比較,第二項是應該待在原位還是插到第一項之前呢?這樣,頭兩項就已正確排序,接著和第三項比較(它是該插入到第一、第二還是第三的位置呢?),以此類推。

排序小型數組時,此演算法比選擇排序和冒泡排序性能要好。

代碼

this.insertionSort = function () {
  console.time('insertionSort');
  var length = array.length,
      j, temp;

  for (var i = 1; i < length; i++) {
    j = i;
    temp = array[i];
    while (j > 0 && array[j-1] > temp) {
      array[j] = array[j-1];
      j--;
    }
    array[j] = temp;
  }
  console.timeEnd('insertionSort');
}

圖解

插入排序

4. 歸併排序

歸併排序是一種分治演算法。其思想是將原始數組切分成較小的數組,直到每個小數組只有一個位置,接著將小數組歸併成較大的數組,直到最後只有一個排序完畢的大數組。

複雜度:O(n log^n)。

代碼

this.mergeSort = function () {
  console.time('mergeSort');
  array = mergeSortRec(array);
  console.timeEnd('mergeSort');
}
var mergeSortRec  = function (array) {
  var length = array.length;
  if (length === 1) {
    return array;
  }

  var mid = Math.floor(length / 2),
      left = array.slice(0, mid),
      right = array.slice(mid, length);

  return merge(mergeSortRec(left), mergeSortRec(right));
}
var merge = function (left, right) {
  var result = [],
      il = 0,
      ir = 0;

  while (il < left.length && ir < right.length) {
    if (left[il] < right[ir]) {
      result.push(left[il++]);
    } else {
      result.push(right[ir++]);
    }
  }

  while (il < left.length) {
    result.push(left[il++]);
  }

  while (ir < right.length) {
    result.push(right[ir++]);
  }

  return result;
}

圖解

歸併排序

5. 快速排序

歸併排序一樣,快速排序也使用分治的方法,將原始數組分為較小的數組(但它沒有像歸併排序那樣將它們分割開)。

它的性能通常比其他的複雜度為O(n log^n)的排序演算法要好。

複雜度:O(n log^n)。

代碼

this.quickSort = function () {
  console.time('quickSort');
  quick(array, 0, array.length - 1);
  console.timeEnd('quickSort');
}

var quick = function (array, left, right) {
  var index;
  if (array.length > 1) {
    index = partition(array, left, right);

    if (left < index - 1) {
      quick(array, left, index - 1);
    }

    if (index < right) {
      quick(array, index, right);
    }
  }
};

// 劃分過程
var partition = function (array, left, right) {
  var pivot = array[Math.floor((right + left) / 2)],
      i = left,
      j = right;

  while (i < j) {
    while (array[i] < pivot) {
      i++;
    }

    while (array[j] > pivot) {
      j--;
    }

    if (i <= j) {
      swapQuickSort(array, i, j);
      i++;
      j--;
    }
  }
  return i;
}

var swapQuickSort = function (array, index1, index2) {
  var aux = array[index1];
  array[index1] = array[index2];
  array[index2] = aux;
}

圖解

快速排序1
快速排序2
快速排序3
快速排序4
快速排序5

6. ECMAScript 排序

ECMAScript沒有定義用哪個排序演算法,所以瀏覽器廠商可以自行去實現演算法。例如,Mozilla Firefox使用歸併排序作為Array.prototype.sort的實現,而Chrome使用了一個快速排序(下麵我們會學習的)的變體。

this.esSort = function () {
  console.time('esSort');
  var tempArray = [];
  tempArray = array.sort(function (a, b) {
    return a - b;
  });
  console.timeEnd('esSort');
  return tempArray;
}

性能測試

環境

  • OS:WIN10 64位

  • 瀏覽器:Google Chrome 60.0.3112.78

代碼

/**
* 創建隨機數組
* @param  {[type]} size [description]
* @return {[type]}      [description]
*/
function createNonSortedArray (size) {
  var array = new ArrayList();
  for (var i = size; i > 0; i--) {
    var tempNum = Math.random() * i >>> 0;
    array.insert(tempNum);
  }
  return array;
}

// 冒泡排序
(function () {
  var array = createNonSortedArray(500);
  array.bubbleSort(); // Bubble Sort: 2.625ms
  console.log(array.val());
}());


// 選擇排序
(function () {
  var array = createNonSortedArray(500);
  array.selectionSort(); // selectionSort: 1.986083984375ms
  console.log(array.val());
}());

// 插入排序
(function () {
  var array = createNonSortedArray(500);
  array.insertionSort(); // insertionSort: 1.825927734375ms
  console.log(array.val());
}());

// 歸併排序
(function () {
  var array = createNonSortedArray(500);
  array.mergeSort(); // mergeSort: 0.76416015625ms
  console.log(array.val());
}());


// 快速排序
(function () {
  var array = createNonSortedArray(500);
  array.quickSort(); // quickSort: 0.39111328125ms
  console.log(array.val());
}());


// ES排序
(function () {
  var array = createNonSortedArray(500);
  array.esSort(); // esSort: 0.34130859375ms
  console.log(array.val());
}());

由此可見,一般情況我們只需要使用JavaScript 提供的 Array.prototype.sort() 方法即可,瀏覽器(或宿主環境)會在底層採用最優演算法幫我們實現排序。

來源/參考

轉載請註明出處: http://blog.givebest.cn/javascript/2017/08/02/javascript-sorting-algorithms.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 放假啦~學生們要買車票回家了,有汽車票、火車票,等。但是,車站很遠,又要考試,怎麼辦呢?找代理買啊,雖然要多花點錢,但是,說不定在搞活動,有折扣呢~ 編譯,運行 ...
  • 本周要進行boost asio庫的學習,在學習之前發現最好需要先瞭解一下前攝器模式,這樣對asio庫的理解很有幫助,故寫下此文 我之前寫的隨筆XShell的模擬實現中的鏈接方式可以說是同步的(伺服器阻塞等待鏈接),這樣當有伺服器端在等待鏈接的時候就浪費了大量的資源,我們可以讓伺服器非同步等待客戶端的鏈 ...
  • 現有一批裝備(產品),分為不同的部位(上裝、下裝)與不同的等級(lv1、lv2)。又有不同lv的工廠,只生產對應lv的全套裝備。 代碼實現上...本次寫得比較偷懶,函數實現都寫在頭文件了.... 有些重覆的代碼,是直接用sed替換一些字元生成的。如: Suit Trousers Clothes Tr ...
  • 1、有一個工廠,專門生產不同品牌的汽車。當有人需要從此工廠提貨的時候,只需要告訴他,要什麼品牌的,就可以了,並不關心這些車是怎麼生產出來的。 2、以上方式,如果增加品牌的時候,也要修改工廠,有點麻煩。於是,把工廠也抽象了。 1的類圖與實現: 首先,是通用的車 然後是不同品牌的車,繼承自Car 接著, ...
  • 項目框架轉換 原來用的是jquery+ace.js框架的項目 現在需要改為現在流行的angularJS框架 本人又不會angularJS,只能一步一步的摸索 路漫漫其修遠兮 吾將上下而求索 剛接觸angularJS 給我的第一感覺是總有和最早期的ASP有些相似 很多前端邏輯 很多界面代碼揉合在一起, ...
  • 最近發現好多網站都採用頂部彈窗,並且不用用戶手動去點擊確定。感覺這樣很方便用戶,所以也找了好多大神的代碼,整理一下方便以後查找 前端: 個人感覺還是很好用的,這個是從某位大神那裡引用來的,如果有冒犯,麻煩告訴我,我會刪除的 下載鏈接:http://pan.baidu.com/s/1hr8vIF6 ...
  • 今天想在Sublime Text(簡稱ST)內編寫HTML後直接使用瀏覽器看效果,想添加View in Browser插件,然後遇到奇怪的問題添加插件直接報"找不到有用的插件" 一開始懷疑是中文破解版的,換成原版的就會好。但是官網上下載原版還是不行,然後上網搜了一下,發現好多人遇到此問題。 接著就一 ...
  • 之前我的旅游網站前端部分只用了HTML+CSS解決,接下來逐步使用更高級的CSS特性和新引入的JavaScript技術來提高網站的交互體驗。 每到進行線上更新的時候,就來記錄一次更新的內容。 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...