思路git
插入排序是全部人都會的排序哪怕他沒有學過計算機。github
插入排序之因此叫插入排序,你能夠這樣理解:算法
假設你在打撲克牌
npm
一般咱們須要將牌排好序,那麼這個時候你是怎樣排序的呢?數組
首先
咱們手裏一張牌都沒有。bash
而後
咱們拿到第一張
牌這時候他不須要排序,也就是說它是有序的
。函數
因此咱們能夠獲得以下代碼。測試
function insertionSort(arr) {
// 第一張牌是有序的直接放入數組
const result = [arr[0]];
return result;
}
複製代碼
緊接着咱們拿到了第二張牌,這張牌可能比手裏原有的牌大,也可能小,也可能相等只是花色不同。ui
這時不論大小與否,你都要肯定你想怎麼排列它,個人意思是你要在升降序這兩個選項裏作一個抉擇。spa
假設你選擇了升序:
(注意:雖然手裏只有一張牌可是,仍是須要遍歷整個牌組。)
那麼若是這張牌比第一張大,你會接着比較這張牌是否比第二張牌大,直到你找出這張牌 比前一張牌大可是比後一張牌小
的位置,將它 插入
. (總結起來就是隻要這張牌比與他比較的牌小就插入在這張牌以前,不然接着比較)
降序則是 比前一張牌小可是比後一張牌大
。
這樣一來新插入的牌因爲出如今合理的位置因此手裏的牌仍然是有序的。
接下來重複上一過程便可將在牌發完的那一刻獲得一個有序的牌組。
寫成代碼是這樣的:
function insertionSort(arr) {
// 第一張牌是有序的直接放入數組
const result = [arr[0]];
const { length } = arr;
// 這層循環是模擬發除第一張牌之外剩下的牌
for (let i = 1; i < length; i++) {
const original = result.length;
// 這層循環是將新發下來的牌與手裏的每一張牌比較看看它比哪張大,比哪張小。
for (let j = 0; j < original; j++) {
// 只要這張牌比與他比較的牌小
if (result[j] > arr[i]) {
// 就插入在這張牌以前
result.splice(j, 0, arr[i]);
// 插入以後結束本輪比較
break;
}
// 不然接着比較
}
// 比全部的都大
}
return result;
}
複製代碼
其中有兩個特殊狀況
一、 這張牌是最小的
最小的牌直接在最前面插入
複製代碼
這種狀況前面的代碼已經包括了直接插入
二、 這張牌是最大的
最大的牌直接在最後面插入
複製代碼
這種狀況的代碼以下:
function insertionSort(arr) {
// 第一張牌是有序的直接放入數組
const result = [arr[0]];
const { length } = arr;
// 這層循環是模擬發除第一張牌之外剩下的牌
for (let i = 1; i < length; i++) {
const oldLen = result.length;
// 這層循環是將新發下來的牌與手裏的每一張牌比較看看它比哪張大,比哪張小。
for (let j = 0; j < oldLen; j++) {
// 只要這張牌比與他比較的牌小
if (result[j] > arr[i]) {
// 就插入在這張牌以前
result.splice(j, 0, arr[i]);
// 插入以後結束本輪比較
break;
}
// 不然接着比較
}
// 比全部的都大說明沒有插入手牌說明手裏的牌沒有增多
if (oldLen === result.length) {
result.push(arr[i]);
}
}
return result;
}
複製代碼
至此排序過程完成須要測試一下。
mocha 是作單元格測試的 npm 包之一。還有其餘的,就不介紹了。
一、首先須要下載 mocha
yarn global add mocha
複製代碼
或者:
sudo npm i mocha -g
複製代碼
二、新建 test.js 文件 或者新建 test/test.js 也行看我的喜愛。
三、官網有一個例子
var assert = require('assert'); // 引入測試包
describe('Array', function() { // 描述 數組
describe('#indexOf()', function() { // 的 indexOf 函數
// 在找不到對應元素的狀況下應該返回 -1
it('should return -1 when the value is not present', function() {
assert.equal([1, 2, 3].indexOf(4), -1); // 第一我的參數是要測試的函數 , 第二個參數是結果 。
});
});
});
複製代碼
結果:
測試一個排序算法是否正確我準備了 4 個例子 (被測試數據 => 指望結果)
一、正整數
[1,3,2] => [1,2,3]
複製代碼
describe('insertionSort([1,3,2])',function(){ // 描述 函數排序 [1,3,2]
it('should return [1,2,3]',function(){ // 應該返回 [1,2,3]
assert.deepEqual( insertionSort([1,3,2]), [1,2,3]) // 第一個參數的返回值應該等於第二個參數
})
})
複製代碼
二、負數
[-1,-3,-2] => [-3,-2,-1]
複製代碼
describe('insertionSort([-1,-3,-2])',function(){
it('should return [-3,-2,-1]',function(){
assert.deepEqual( insertionSort([-1,-3,-2]), [-3,-2,-1] )
})
})
複製代碼
三、小數
[0.1,-0.1,0] => [-0.1,0,0.1]
複製代碼
describe('insertionSort([0.1,-0.1,0])',function(){
it('should return [-0.1,0,0.1]',function(){
assert.deepEqual( insertionSort([0.1,-0.1,0]), [-0.1,0,0.1] )
})
})
複製代碼
四、 綜合
[3,2,1,11,22,33,-33,-22,-11,-3,-4,-5,3.3,1.1,1.01,3,2,1]
=>
[-33, -22, -11, -5, -4, -3, 1, 1, 1.01, 1.1, 2, 2, 3, 3, 3.3, 11, 22, 33]
複製代碼
describe('insertionSort([3,2,1,11,22,33,-33,-22,-11,-3,-4,-5,3.3,1.1,1.01,3,2,1])',function(){
it('should return [-33, -22, -11, -5, -4, -3, 1, 1, 1.01, 1.1, 2, 2, 3, 3, 3.3, 11, 22, 33]',function(){
assert.deepEqual( insertionSort([3,2,1,11,22,33,-33,-22,-11,-3,-4,-5,3.3,1.1,1.01,3,2,1]), [-33, -22, -11, -5, -4, -3, 1, 1, 1.01, 1.1, 2, 2, 3, 3, 3.3, 11, 22, 33] )
})
})
複製代碼
測試結果:
(完)