寫在前面
本文是學習"ben大叔"大佬的相關文章所總結而成。
作爲一名前端,你可以不瞭解複雜的一些算法實現,但是關於排序算法你可要了解和掌握哦,比如以下這幾種:
冒泡排序簡介
冒泡排序作爲排序算法家族中的成員來說,相當於編程語言學習中的"Hello World",因爲它是最簡單的排序算法。冒泡排序會重複走訪待排序序列,每次會比較序列中的相鄰兩個元素,如果這兩個元素的順序錯誤,就將它倆位置互換,依次重複進行此操作,直到待排序序列中沒有要進行交換的操作爲止,就意味着已經完成了排序。由於冒泡排序中每次重複比較兩個元素、交換位置的過程中,值較小的數據往往會被排到數列的前面,值越大的數據會往後排,這就像是水裏的水泡一樣往上冒,所以它的名字由此而來。
冒泡排序實現過程
- 比較相鄰的兩個元素,如果第一個比第二個大,就交換它們位置;
- 對待排序序列中的每一對相鄰元素做上面重複操作,從最開始的一對到最後的一對,這樣每次一輪比較結束後,結尾的元素是最大的數;
- 重複以上兩個步驟,直到排序完成。
冒泡排序的動圖演示
冒泡排序代碼實現
function bubbleSort(arr) {
var len = arr.length;
for(var i = 0; i < len - 1; i++) {
for(var j = 0; j < len - 1 - i; j++) {
if(arr[j + 1] < arr[j]) {
var middle = arr[j+1];
arr[j+1] = arr[j];
arr[j] = middle;
}
}
}
return arr;
};
var defaultArr = [3, 5, 32, 15, 7, 26, 10, 55, 45, 12, 28, 88, 18]; //待排序序列
var resultArr = bubbleSort(defaultArr);
console.table(resultArr);
可以通過上面代碼看到,冒泡排序的實現原理就是雙重循環,如果後一個數小於前一個數,就替換它們的位置,這樣重複進行直至循環結束。它每次比較時都將數值較大的數據放在結尾,所以將我們的數組實際上是從小到大進行了排序,同理,要想實現從大到小排序,我們只需要將條件判斷語句中的小於號改成大於號即可。
冒泡排序應用場景
- 比較適用於小數據量的排序(從小到大或者從大到小),因爲原理簡單,並且數據量大的話循環次數極多,降低性能;
- 適用於教學,因爲原理簡單。
冒泡排序的算法口訣
- 外層循環從0到N-1; (控制比較的輪數,N爲元素個數)
- 內層循環從0到N-1-i; (控制每一輪比較次數)
- 兩兩比較作交換。
冒泡排序的優化
我們上述實現的僅僅是冒泡排序的基礎版,也就是實現了一個能用的冒泡排序算法而已,如果數據量較大的話,它的性能是極低的,所以接下來我們優化一下(雖然並沒有實質性的作用,但還是介紹下)。
冒泡排序的優化大家記住一點即可:冒泡排序優化其實就是減少比較次數,本質上不會有較大的性能提升。
1、添加flag的方式
//flag版優化
function bubbleSort_flag(arr) {
var len = arr.length;
var flag = false; //添加一個flag,用於標識原序列是否是一個有序序列
if(len <= 1) { //如果僅僅有一個元素直接返回
return arr;
}
for(var i = 0; i < len - 1; i++) {
for(var j = 0; j < len - 1 - i; j++) {
if(arr[j + 1] < arr[j]) {
var middle = arr[j+1];
arr[j+1] = arr[j];
arr[j] = middle;
flag = true;
}
}
if(!flag) break; //如果一次都沒有發生數據交換就返回原序列,因爲已經是一個有序序列
}
return arr;
}
var defaultArr = [3, 5, 32, 15, 7, 26, 10, 55, 45, 12, 28, 88, 18];
var resultArr = bubbleSort_flag(defaultArr);
console.table(resultArr);
2、雙向冒泡排序(雞尾酒排序)
基礎版的冒泡排序是從一端開始,依次循環比較相鄰元素實現的,爲了減少比較次數,略微的提高一下性能,我們可以選擇讓排序從兩頭開始,即遵循"較大氣泡從左往右移動,較小氣泡從右往左移動"的方式來實現,如下:
//雙向冒泡排序
function bubbleSort_twoway(arr) {
var len = arr.length; //依次將最大的數放置到數組末尾,將第二大的數放到倒數第二位...
var flag = false;
for(var i = 0; i < len/2; i++) {
flag = false;
for(var j = i; j < len - 1 - i; j++) { //從前往後,比較相鄰兩個數,把大的放在後邊.之前已放置成功的可以不再參與比較
if(arr[j] > arr[j + 1]) {
var middle = arr[j];
arr[j] = arr[j+1];
arr[j+1] = middle;
flag =true;
}
}
if(!flag){
break;
}
for(var j = len - 1 - i; j > i; j--){
if(arr[j] < arr[j - 1]) {
var middle = arr[j];
arr[j] = arr[j-1];
arr[j-1] = middle;
flag = true;
}
}
if(!flag){
break;
}
}
return arr;
}
var defaultArr = [3, 5, 32, 15, 7, 26, 10, 55, 45, 12, 28, 88, 18];
var resultArr = bubbleSort_twoway(defaultArr);
console.table(resultArr);
冒泡排序優缺點:
- 優點:簡單、空間複雜度低、穩定
- 缺點:時間複雜度高、效率低