完成數組排序的算法許多,个中冒泡算法是比較簡樸的
冒泡的基本道理是相鄰的兩個數舉行比較,根據排序的前提舉行交流,比方對數值從小到大排序,
跟着不停的交流,最大的誰人值會逐步冒泡到數組的末尾
基於這個道理我們就可以夠寫冒泡排序了
為了簡樸起見下面的例子都是對數值數組舉行從小到大排序,先模仿一個20個字符的數組
function getRandomArr(n) {
let arr = [];
for (let i = 0; i < n; i++) {
arr.push(~~(Math.random() * 100));
}
return arr
}
let randomArr = getRandomArr(20);
第一種冒泡算法
從道理可知,冒泡算法起碼是須要2層輪迴的,當个中一個數值冒泡到末尾時,這個數值下次就不須要介入輪迴了,如許輪迴的局限就會逐步減少,末了數組完成排序
function bubbleSort(arr) {
let len = arr.length;
let temp;
let i = len - 1;
while(i > 0) {
for (let j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
i--;//不停減少局限
}
return arr;
}
console.log(randomArr)//[ 93, 72, 29, 17, 82, 26, 56, 71, 35, 48, 37, 42, 3, 11, 33, 66, 81, 53, 59, 53 ]
console.log('bubbleSort', bubbleSort(randomArr.concat()));//bubbleSort [ 3, 11, 17, 26, 29, 33, 35, 37, 42, 48, 53, 53, 56, 59, 66, 71, 72, 81, 82, 93 ]
在冒泡的過程當中,我們能夠發明,假如數組背面部份已排好序了,也就是不必再交流兩邊的位置時,只需紀錄好末了一次交流的位置,就有很大的能夠減少下次輪迴的局限,如許就可以進步冒泡的機能(這隻是猜測)
第二種冒泡算法
function bubbleSort2(arr) {
let len = arr.length;
let i = len - 1;
let temp;
let pos;//用來紀錄位置的
while (i > 0) {
pos = 0;//初始為0假如數組一開始已排好序了,那末就可以夠很快停止冒泡
for (let j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
pos = j;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
i = pos;
}
return arr;
}
console.log(randomArr)//[47, 31, 85, 65, 44, 56, 54, 5, 67, 44, 76, 13, 90, 12, 83, 72, 2, 69, 58, 60]
console.log('bubbleSort2', bubbleSort2(randomArr.concat()));//bubbleSort2 [2, 5, 12, 13, 31, 44, 44, 47, 54, 56, 58, 60, 65, 67, 69, 72, 76, 83, 85, 90]
實在關於第一種輪迴,是從左到右舉行冒泡,我們也能夠從右到左冒泡,然則從右到左的要領和第一種基本就一樣了,然則我們能夠在內層輪迴中完成先向左冒泡,再向右冒泡
第三種冒泡要領
function bubbleSort3(arr) {
let len = arr.length;
let low = 0;
let higth = len - 1;
let temp;
while (low < higth) {
for (let j = low; j < higth; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
higth--;
for (let j = higth; j > low; j--) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
low++;
}
return arr;
}
console.log(randomArr)//[40, 78, 16, 97, 38, 27, 66, 44, 45, 31, 12, 1, 99, 68, 36, 42, 40, 54, 6, 42]
console.log('bubbleSort3', bubbleSort3(randomArr.concat()));//bubbleSort3 [1, 6, 12, 16, 27, 31, 36, 38, 40, 40, 42, 42, 44, 45, 54, 66, 68, 78, 97, 99]
末了能夠連繫第三種和第二種要領
第四種冒泡的要領
function bubbleSort4(arr) {
let len = arr.length;
let low = 0;
let higth = len - 1;
let temp;
while (low < higth) {
let hPos = 0;
let lPos = higth;
for (let j = low; j < higth; j++) {
if (arr[j] > arr[j + 1]) {
hpos = j;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
heigth = hPos;
for (let j = higth; j > low; j--) {
if (arr[j] < arr[j - 1]) {
lPos = j;
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
low = lPos;
}
return arr;
}
console.log(randomArr)//[40, 78, 16, 97, 38, 27, 66, 44, 45, 31, 12, 1, 99, 68, 36, 42, 40, 54, 6, 42]
console.log('bubbleSort4', bubbleSort4(randomArr.concat()));//[1, 6, 12, 16, 27, 31, 36, 38, 40, 40, 42, 42, 44, 45, 54, 66, 68, 78, 97, 99]
下面臨這4種要領在chrome掌握台下舉行一個簡樸的機能測試
var randomArr = getRandomArr(10000);
console.time('1');
bubbleSort(randomArr.concat());
console.timeEnd('1');
console.time('2');
bubbleSort2(randomArr.concat());
console.timeEnd('2');
console.time('3');
bubbleSort3(randomArr.concat());
console.timeEnd('3');
console.time('4');
bubbleSort4(randomArr.concat());
console.timeEnd('4');
VM371:4 1: 329.705ms
VM371:7 2: 379.501ms
VM371:10 3: 310.843ms
VM371:13 4: 306.847ms
在經由屢次測試發明一個風趣的徵象實行最快的是第4種要領,最慢的是第2種,沒錯最慢的是我以為能夠進步機能的第2種要領,這就相稱為難了,不知道有哪位小夥伴能夠解釋一下