自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

6大排序算法

開發(fā) 算法
這次梳理了一遍6種排序算法,從掌握思想到實現(xiàn)它,還是畫了不少時間,又通過筆記梳理一遍,正好整理出來,對大家起一個拋磚引玉的效果吧。

 6中常見的排序算法有GIF動圖,更加容易幫助你理解其中的排序思想。

6種排序如下👇

冒泡排序
計數(shù)排序
快速排序
歸并排序
插入排序
選擇排序
時間復雜度如下圖👇

 

排序算法復雜度分析
冒泡排序
以下動圖GIF來自知乎 帥地

冒泡排序
這個名字的由來是向泡泡一樣浮起來,腦補一下,就是每次比較相鄰的兩個元素大小,然后慢慢'漂浮'起來,看思路吧。

「時間復雜度O(n*n)」

思路
1 比較相鄰的元素,前者比后者大的話,兩者交換位置。
2 對每一對相鄰元素做相同操作,從開始第一對到最后一對,這樣子最后的元素就是最大元素。
3 針對n個元素重復以上步驟,每次循環(huán)排除當前最后一個。
4 重復步驟1~3,直到排序完成。

代碼實現(xiàn)

  1. // 最外層循環(huán)控制的內容是循環(huán)次數(shù) 
  2. // 每一次比較的內容都是相鄰兩者之間的大小關系 
  3. let BubbleSort = function (arr, flag = 0) { 
  4.     let len = arr.length 
  5.  
  6.     for (let i = 0; i < len - 1; i++) { 
  7.         for (let j = 0; j < len - 1 - i; j++) { 
  8.             if (arr[j] > arr[j + 1]) { 
  9.                 [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]] 
  10.             } 
  11.         } 
  12.     } 
  13.     return flag ? arr.reverse() : arr 
  14.  
  15. let arr = [2, 9, 6, 7, 4, 3, 1, 7] 
  16. console.log(BubbleSort(arr, 1)) 

計數(shù)排序
從名稱上就知道,它的思想:就是把數(shù)組元素作為數(shù)組的下標,然后用一個臨時數(shù)組統(tǒng)計該元素出現(xiàn)的次數(shù)。

數(shù)組的數(shù)據(jù)必須是整數(shù),而且最大最小值相差的值不要過大,對于「數(shù)據(jù)是負數(shù)的話,我實現(xiàn)的方案對此有優(yōu)化」。

「時間復雜度:O(n+k)」

思路
1.計算出差值d,最小值小于0,加上本身add

2.創(chuàng)建統(tǒng)計數(shù)組并統(tǒng)計對應元素個數(shù)

3.統(tǒng)計數(shù)組做變形,后面的元素等于前面的元素之和,也就是排名數(shù)組

4.遍歷原始數(shù)組,從統(tǒng)計數(shù)組中找到正確位置,輸出到結果數(shù)組

動畫

計數(shù)排序
代碼實現(xiàn)

  1. // 計數(shù)排序 
  2. let countingSort = function(arr, flag = 0) { 
  3.     let min = arr[0], 
  4.         max = arr[0], 
  5.         len = arr.length; 
  6.     // 求最大最小值 
  7.     for(let i = 0; i < len; i++) { 
  8.         max = Math.max(arr[i], max
  9.         min = Math.min(arr[i], min
  10.     } 
  11.     // 1.計算出差值d,最小值小于0,加上本身add 
  12.  
  13.     let d =  max - min
  14.         add = min < 0 ? -min : 0; 
  15.     //2.創(chuàng)建統(tǒng)計數(shù)組并統(tǒng)計對應元素個數(shù)     
  16.     let countArray  = new Array(d+1+add).fill(0) 
  17.     for(let i = 0; i < len; i++){ 
  18.         let demp = arr[i]- min + add 
  19.         countArray[ demp ] += 1  
  20.     } 
  21.      
  22.     //3.統(tǒng)計數(shù)組做變形,后面的元素等于前面的元素之和,也就是排名數(shù)組 
  23.     let sum = 0; 
  24.  
  25.     // 這里需要遍歷的是countArray數(shù)組長度 
  26.     for(let i = 0; i < d+1+add; i++){ 
  27.         sum += countArray[i] 
  28.         countArray[i] = sum
  29.     } 
  30.     let res = new Array(len) 
  31.     //4.遍歷原始數(shù)組,從統(tǒng)計數(shù)組中找到正確位置,輸出到結果數(shù)組 
  32.     for(let i = 0; i < len; i++){ 
  33.         let demp = arr[i] -min + add 
  34.         res[ countArray[demp] -1 ] = arr[i] 
  35.         countArray[demp] --; 
  36.     } 
  37.     return flag ? res.reverse() : res 
  38.  
  39. let arr = [2, 9, 6, 7, 4, 3, 1, 7,0,-1,-2] 
  40. console.log(countingSort(arr)) 

快速排序
基本思想:通過一趟排序將待排記錄分隔成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分的關鍵字小,則可分別對這兩部分記錄繼續(xù)進行排序,以達到整個序列有序。

「時間復雜度:O(nlogn)」

思路
選擇數(shù)組中間數(shù)作為基數(shù),并從數(shù)組中取出此基數(shù)
準備兩個數(shù)組容器,遍歷數(shù)組,逐個與基數(shù)比對,較小的放左邊容器,較大的放右邊容器;
遞歸處理兩個容器的元素,并將處理后的數(shù)據(jù)與基數(shù)按大小合并成一個數(shù)組,返回。
動畫

快速排序

  1. let quickSort = function (arr) { 
  2.     // 遞歸出口就是數(shù)組長度為1 
  3.     if (arr.length <= 1) return arr 
  4.     //獲取中間值的索引,使用Math.floor向下取整; 
  5.     let index = Math.floor(arr.length / 2) 
  6.     // 使用splice截取中間值,第一個參數(shù)為截取的索引,第二個參數(shù)為截取的長度; 
  7.     // 如果此處使用pivot=arr[index]; 那么將會出現(xiàn)無限遞歸的錯誤; 
  8.     // splice影響原數(shù)組 
  9.     let pivot = arr.splice(index, 1)[0], 
  10.         left = [], 
  11.         right = []; 
  12.     console.log(pivot) 
  13.     console.log(arr) 
  14.     for (let i = 0; i < arr.length; i++) { 
  15.         if (pivot > arr[i]) { 
  16.             left.push(arr[i]) 
  17.         } else { 
  18.             right.push(arr[i]) 
  19.         } 
  20.     } 
  21.     return quickSort(left).concat([pivot], quickSort(right)); 
  22.  
  23. //let arr = [2, 9, 6, 7, 4, 3, 1, 7] 
  24. // console.log(quickSort(arr)) 

歸并排序

將兩個有序數(shù)列合并成一個有序數(shù)列,我們稱之為“歸并”

基本思想與過程:先遞歸的分解數(shù)列,再合并數(shù)列(分治思想的典型應用)

「時間復雜度: O(nlog(n))」

思路
將一個數(shù)組拆成A、B兩個小組,兩個小組繼續(xù)拆,直到每個小組只有一個元素為止。
按照拆分過程逐步合并小組,由于各小組初始只有一個元素,可以看做小組內部是有序的,合并小組可以被看做是合并兩個有序數(shù)組的過程。
對左右兩個小數(shù)列重復第二步,直至各區(qū)間只有1個數(shù)。
動畫

歸并排序
代碼實現(xiàn)

  1. const merge = (leftright) => { // 合并數(shù)組 
  2.  
  3.     let result = [] 
  4.     // 使用shift()方法偷個懶,刪除第一個元素,并且返回該值 
  5.     while (left.length && right.length) { 
  6.         if (left[0] <= right[0]) { 
  7.             result.push(left.shift()) 
  8.         } else { 
  9.             result.push(right.shift()) 
  10.         } 
  11.     } 
  12.     while (left.length) { 
  13.         result.push(left.shift()) 
  14.     } 
  15.  
  16.     while (right.length) { 
  17.         result.push(right.shift()) 
  18.     } 
  19.     return result 
  20.  
  21. let mergeSort = function (arr) { 
  22.     if (arr.length <= 1) 
  23.         return arr 
  24.     let mid = Math.floor(arr.length / 2) 
  25.     // 拆分數(shù)組 
  26.     let left = arr.slice(0, mid), 
  27.         right = arr.slice(mid); 
  28.     let mergeLeftArray = mergeSort(left), 
  29.         mergeRightArray = mergeSort(right
  30.     return merge(mergeLeftArray, mergeRightArray) 
  31.  
  32. let arr = [2, 9, 6, 7, 4, 3, 1, 7, 0, -1, -2] 
  33. console.log(mergeSort(arr)) 

插入排序
顧名思義:通過構建有序序列,對于未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應位置并插入。

「時間復雜度: O(n*n)」

思路
從第一個元素開始,該元素可以認為已經被排序;
取出下一個元素,在已經排序的元素序列中從后向前掃描;
如果該元素(已排序)大于新元素,將該元素移到下一位置;
重復步驟3,直到找到已排序的元素小于或者等于新元素的位置;
重復步驟2~5。

代碼實現(xiàn)

  1. let insertionSort = function (arr) { 
  2.     let len = arr.length 
  3.  
  4.     for (let i = 0; i < len; i++) { 
  5.         let preIndex = i - 1, 
  6.             cur = arr[i]; 
  7.         while (preIndex >= 0 && arr[preIndex] > cur) { 
  8.             arr[preIndex + 1] = arr[preIndex] 
  9.             preIndex--; 
  10.         } 
  11.         arr[preIndex + 1] = cur 
  12.     } 
  13.     return arr 
  14.  
  15.  
  16. let arr = [2, 9, 6, 7, 4, 3, 1, 7, 0, -1, -2] 
  17. console.log(insertionSort(arr)) 

選擇排序
思路:每一次從待排序的數(shù)組元素中選擇最大(最小)的一個元素作為首元素,直到排完為止

「時間復雜度O(n*n)」

思路
1.有n個數(shù),需要排序n-1次
2.第一次選擇最小值,放在第一位
3.第二次選擇最小值,放在第二位
4.…..重復該過程
5.第n-1次選擇最小值,放在第n-1位
代碼實現(xiàn)

  1. let selectSort = function (arr, flag = 0) { 
  2.     let len = arr.length, 
  3.         temp = 0; 
  4.  
  5.     // 一共需要排序len-1次 
  6.     for (let i = 0; i < len - 1; i++) { 
  7.         temp = i; 
  8.         for (let j = i + 1; j < len; j++) { 
  9.             if (arr[j] < arr[temp]) 
  10.                 temp = j; 
  11.         } 
  12.         // 每一趟保證第i位為最小值 
  13.         if (temp !== i) { 
  14.             [arr[i], arr[temp]] = [arr[temp], arr[i]] 
  15.         } 
  16.     } 
  17.  
  18.     return flag ? arr.reverse() : arr 
  19.  
  20.  
  21.  
  22. let arr = [2, 9, 6, 7, 4, 3, 1, 7, 0, -1, -2] 
  23. console.log(selectSort(arr, 1)) 

 

 

責任編輯:姜華 來源: 前端UpUp
相關推薦

2015-11-12 11:05:07

java排序算法

2015-10-08 09:08:50

Python實現(xiàn)

2021-08-25 09:59:00

開發(fā)排序代碼

2018-10-10 14:03:00

Java開發(fā)代碼

2016-09-30 14:23:16

數(shù)據(jù)結構算法八大排序算法

2019-05-29 17:45:32

JavaScript算法思路代碼實現(xiàn)

2020-11-25 10:40:58

程序員技能開發(fā)者

2016-12-07 10:42:57

排序算法實例

2012-06-28 14:01:30

Java程序員排序

2020-08-16 11:37:27

Python開發(fā)工具

2019-12-26 14:50:36

ORDER BY數(shù)據(jù)庫排序函數(shù)

2016-11-21 11:59:19

排序算法Objective-C

2021-01-21 05:22:36

排序算法選擇

2021-01-26 05:33:07

排序算法快速

2021-10-31 07:38:37

排序算法代碼

2017-07-18 10:50:38

前端JavaScript排序算法

2022-03-10 12:03:33

Python算法代碼

2023-10-05 09:01:05

插入排序對象序列log2i

2018-11-14 09:40:05

排序算法Java編程語言

2011-04-20 14:07:37

冒泡排序
點贊
收藏

51CTO技術棧公眾號