摘要:總結一下,插入排序優于選擇排序。插入排序可以提前終止內層循環,如果數組近乎有序,那么效率會很高。我的寫的不是最好的,僅僅是解釋概念,有興趣的同學可以自己寫一個更好的插入排序和選擇排序。
我覺得作為前端學學算法也是有益處的吧,所以今天就先來講講最基礎的排序算法。提升我們程序員的內功~
插入排序插入排序是n^2的基礎排序方法,大致思想是假設一個數組的前n個元素已經有序,然后考慮把第n+1個未排序的元素給插入到有序數組中去。現將n+1和第n個元素比較,如果n+1比n小,那么就交換一下位置。之后我們要排序的元素就在n這個位置上了,接著我們繼續比較n和第n-1個元素的大小。如此反復,直到我們要插入的元素找到適合他的位置。
下面來示范一下
6--7--8--9--3--1--4--6--3--8--9--5
6--7--8--9已經有序,我們要插入的元素是n=4這個元素3。比較9和3的大小,9比3大。交換一下位置
6--7--8--3--9,就變成了這個樣子。接著比較8和3的大小,8比3大,交換一下位置
6--7--3--8--9,繼續比較7和3的大小,7比3大,交換一下位置
6--3--7--8--9,繼續比較6和3的大小,6比3大,交換一下位置
3--6--7--8--9。到這里循環結束,就已經排好序了。接著比較第n=5的元素1應該插入的位置,如此往復就把數組給排好了序了。
一下是代碼。
//寫一個隨機生成數組的函數 function randomArr(count) { var arr = [] for (var i = 0; i < count; i++) { var number = Math.ceil(Math.random() * 5000) arr.push(number) } return arr } // 交換元素位置的函數 function swap(arr, i, j) { var temp = arr[i] arr[i] = arr[j] arr[j] = temp } var arr = randomArr(5000) // 插入排序函數 function insertionSort(arr) { var length = arr.length // 第0個元素默認就是有序的,因為只有一個元素,所以從第一個元素開始。arr[i]就是要插入的那個元素 for (var i = 1; i < length; i++) { // 從第i-1個元素往前都是已經排好序的元素。所以最后一個開始往前比較 for (var j = i - 1; j >= 0; j--) { // 這里的j+1等于i這個元素。也就是arr[i] === arr[j+1] if (arr[j] > arr[j + 1]) { swap(arr, j + 1, j) } else { break } } } return arr } insertionSort(arr)
由于是兩層for循環,所以它的時間復雜度是n^2級別的。
到這里其實還沒有完,插入排序還是有可以優化的地方的。現在的這個插入排序函數要swap頻繁的交換位置,我們可以這樣
function insertionSort(arr) { var length = arr.length // 第0個元素默認就是有序的,因為只有一個元素,所以從第一個元素開始。arr[i]就是要插入的那個元素 for (var i = 1; i < length; i++) { // **用一個變量保存要插入的元素** var value = arr[i] // 從第i-1個元素往前都是已經排好序的元素。所以最后一個開始往前比較 for (var j = i - 1; j >= 0; j--) { // 這里的j+1等于i這個元素。也就是arr[i] === arr[j+1] if (arr[j] > value) { // 如果比要插入的元素大,把值arr[j]往右移一位 arr[j+1] = arr[j] // 邊界條件,直到j等于0的時候終止循環,將value賦給arr[0],結束循環 if (j === 0){arr[j] = value; break} } else { // 否則把value賦給arr[j]循環結束 arr[j] = value break } } } return arr }
雖然插入排序是n^2級別的算法,但是在一個近乎有序的數組里去實現插入排序,那么他的效率會變的非常高。
因為插入排序可以提前break掉內層循環。有興趣可以寫一個生成近乎有序數組的函數去實驗一下。
// 近乎有序數組 function nearlySorted(arr) { return arr }選擇排序
選擇排序就是在循環中不停的選擇最小的元素,然后交換位置。
下面來示范一下
6--7--8--9--3--1--4--6--3--8--9--5
找到數組中最小的元素1,然后記錄1的位置是5。接著交換位置變成
1--7--8--9--3--6--4--6--3--8--9--5
接著在剩下的數組里7--8--9--3--6--4--6--3--8--9--5找到最小的元素3,記錄下它的下標位置是4,然后交換位置變成
1--3--8--9--7--6--4--6--3--8--9--5。如此往復直到排好序。
function randomArr(count) { var arr = [] for (var i = 0; i < count; i++) { var number = Math.ceil(Math.random() * 5000) arr.push(number) } return arr } function swap(arr, i, j) { var temp = arr[i] arr[i] = arr[j] arr[j] = temp } var arr = randomArr(5000) function selectionSort(arr) { var length = arr.length var value, pos for (var i = 0; i < length; i++) { value = arr[i] pos = i for (var j = i; j < length; j++) { var cur = arr[j] if (value > cur) { value = cur pos = j } } swap(arr, i, pos) } return arr } selectionSort(arr)
到此兩個基礎排序就實現了。總結一下,插入排序優于選擇排序。
插入排序可以提前終止內層循環,如果數組近乎有序,那么效率會很高。而選擇排序無法提前終止循環。
不過最好的排序算法還是nlogn級別的算法。如歸并排序和快速排序。
我的寫的不是最好的,僅僅是解釋概念,有興趣的同學可以自己寫一個更好的插入排序和選擇排序。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94505.html
本篇有7k+字, 系統梳理了js中常見的12種排序算法。除了基本排序算法,文章還包含了希爾排序、堆排序、桶排序等較為復雜的排序實現,如果喜歡請點贊支持~謝謝. 原文: http://louiszhai.github.io/20... 導讀 排序算法可以稱得上是我的盲點, 曾幾何時當我知道Chrome的Array.prototype.sort使用了快速排序時, 我的內心是奔潰的(啥是快排, 我只知道...
摘要:之所以把冒泡排序選擇排序插入排序放在一起比較,是因為它們的平均時間復雜度都為。其中,冒泡排序就是原地排序算法。所以冒泡排序是穩定的排序算法。選擇排序思路選擇排序算法的實現思路有點類似插入排序,也分已排序區間和未排序區間。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 1. 前言 算法為王。 想學好前端,先練好內功,...
摘要:適用于數據比較少或基本有序的情況。插入排序時間復雜度為,空間復雜度為,屬于穩定排序。算法適用于少量數據的排序。就像下圖這樣,可以理解桶的意思下圖是整個排序過程示意圖基數排序時間復雜度為,空間復雜度為,屬于穩定排序。 寫在前面 個人感覺:javascript對類似排序查找這樣的功能已經有了很好的封裝,以致于當我們想對數組排序的時候只需要調用arr.sort()方法,而查找數組元素也只需要...
摘要:本文對一些排序算法進行了簡單分析,并給出了的代碼實現。平均時間復雜度不好分析,它是冒泡排序是穩定的排序算法。冒泡排序是原地排序算法原地排序指的是空間復雜度是的排序算法。歸并排序,會將數組從中間分成左右兩部分。 本文對一些排序算法進行了簡單分析,并給出了 javascript 的代碼實現。因為本文包含了大量的排序算法,所以分析不會非常詳細,適合有對排序算法有一定了解的同學。本文內容其實不...
摘要:實現插入排序插入排序是一種非常簡單的算法,最適合大部分已經被排好序的數據。由此才有了這個名字插入排序。插入排序的最壞情況是輸入的數組是按逆序排序的。總結當輸入的數組已經大部分被排好序時,插入排序的效果最佳。 翻譯:瘋狂的技術宅https://medium.com/@jimrottin... 本文首發微信公眾號:前端先鋒歡迎關注,每天都給你推送新鮮的前端技術文章 插入排序的工作原理...
閱讀 3540·2019-08-30 12:58
閱讀 923·2019-08-29 16:37
閱讀 2796·2019-08-29 16:29
閱讀 3105·2019-08-26 12:18
閱讀 2365·2019-08-26 11:59
閱讀 3405·2019-08-23 18:27
閱讀 2770·2019-08-23 16:43
閱讀 3301·2019-08-23 15:23