js數值排序中冒泡算法的4種簡樸完成

完成數組排序的算法許多,个中冒泡算法是比較簡樸的
冒泡的基本道理是相鄰的兩個數舉行比較,根據排序的前提舉行交流,比方對數值從小到大排序,
跟着不停的交流,最大的誰人值會逐步冒泡到數組的末尾
基於這個道理我們就可以夠寫冒泡排序了

為了簡樸起見下面的例子都是對數值數組舉行從小到大排序,先模仿一個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種要領,這就相稱為難了,不知道有哪位小夥伴能夠解釋一下

    原文作者:changli
    原文地址: https://segmentfault.com/a/1190000014616654
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞