算法筆記(1)

記錄一下最近用到的幾種常見算法的優劣。下面將給出四種算法的javascript代碼和對10w條數據進行排序的結果,10w條數據使用Math.random產生10w條隨機整數。在對1w條一下的數據進行排序時,大多數算法都在毫秒的差距上體現不出來。

實驗源碼在末尾給出。

冒泡排序,選擇排序,插入排序,快速快速。

用js進行測試。

  • 冒泡排序

冒泡排序作爲最基礎的排序算法,他的算法相對簡單,關於原理,不再贅述,本文只是給出個人使用產生的一些感想。

它的性能也是這四種算法中最差的一個。

function bubblingSort() {
    let start = Date.now();
    for (let x=0;x<this.data.length;x++) {
      for (let y=x+1;y<this.data.length;y++) {
        if (this.data[x]>this.data[y]) {
          let tmp = this.data[x];
          this.data[x] = this.data[y];
          this.data[y] = tmp;
        }
      }
    }
    // console.log("paoSort:",this.data.toString());
    console.log("paoSort time: ",Date.now() - start);
  }

冒泡排序對10w條數據排序的時間(結果都是進行反覆測試的,隨機選擇一條):

paoSort time:  15727 (毫秒)

  • 選擇排序

選擇排序的原理和冒泡排序大致相同,都是一次次的找出最大或者最小的數據然後放在首位或者最後一位。但兩者唯一的不同是,冒泡排序每當有排序變動時會立刻進行數據位置的交換,而選擇排序會在當前一輪比較進行完之後才進行數據位置的交換。這也是兩者算法消耗時間不同的原因。因爲數據位置的交換涉及到底層內存的變動,變動過多肯定會消耗更多的時間。

function selectSort() {
    let start = Date.now();
    for (let x=0;x<this.data.length-1;x++) {
      let min = x;
      for (let y=x+1;y<this.data.length;y++) {
        if (this.data[min]>this.data[y]) {
          min = y;
        }
      }
      if (x !== min) {
        let tmp = this.data[x];
        this.data[x] = this.data[min];
        this.data[min] = tmp;
      }
    }
    // console.log("selectSort:",this.data.toString());
    console.log("selectSort time: ",Date.now() - start);
  }

選擇排序對10w條數據排序消耗的大致時間是:

selectSort time:  6359(毫秒)

可以看到,10w條數據排序適,選擇排序明顯優於冒泡排序

  • 插入排序

插入排序是將數據隊列的第一個元素作爲一個有序的數據隊列,然後將後面的數據依次按大小插入到前面的有序數據隊列中,最終完成對整個數據隊列的排序,它的性能要高於前面二種算法。

function insertSort() {
    let start = Date.now();
    for (let x=1;x<this.data.length;x++) {
      if (this.data[x] < this.data[x-1]) {
        let tmp = this.data[x];
        for (let y=x;y>=0;y--) {
          if (y>0 && this.data[y-1]>tmp) {
            this.data[y] = this.data[y-1];
          } else {
            this.data[y] = tmp;
            break;
          }
        }
      }
    }
    // console.log("insert÷Sort:",this.data.toString());
    console.log("insertSort time: ",Date.now() - start);
  }

插入排序對10w條數據進行排序消耗的時間:

insertSort time:  3246(毫秒)

可以看到,插入排序的性能又要明顯高於冒泡和選擇。

  • 快速排序

快速排序是先從數據隊列中選出一個基準值,這個值可以是數據隊列中任意一個元素(一般選擇第一個或者中間的或者最後一個)。然後將小於這個基準值的元素放到左邊,大於的放到右邊。然後遞歸的對左邊的和右邊的數據子隊列再次進行排序,直到左邊,右邊的元素隊列長度爲1。這樣對數據隊列就排序完了。

function fastSortFunc(data) {
    if (data.length <= 1) return data;
    let left  =[],right = [];
    let sign = data[0];
    for (let x=1;x<data.length;x++) {
      data[x] <= sign ? left.push(data[x]) : right.push(data[x]);
    }
    return this.fastSortFunc(left).concat(sign,this.fastSortFunc(right));
  }

快速排序對10w條進行排序的消耗時間:

fastSort time 74(毫秒)

可以看到快速排序的性能遠高於前面的三種算法。實際上,快速算法在算法學中屬於高級算法的一種。前面三種算法屬於基本算法。

 

此次算法比較的源碼:

function TestArr(len) {
  this.data = new Array(len);
  for (let i=0;i<len;i++) {
    this.data[i] = Math.floor(Math.random()*len+1);
    // this.data = i;
  }
  // console.log("init data:",this.data.toString());

  this.paoSort = function () {
    let start = Date.now();
    let num = 0;
    for (let x=0;x<this.data.length;x++) {
      for (let y=x+1;y<this.data.length;y++) {
        num++;
        if (this.data[x]>this.data[y]) {
          let tmp = this.data[x];
          this.data[x] = this.data[y];
          this.data[y] = tmp;
        }
      }
    }
    console.log("num:",num);
    // console.log("paoSort:",this.data.toString());
    console.log("paoSort time: ",Date.now() - start);
  }
  this.selectSort = function () {
    let start = Date.now();
    let num = 0;
    for (let x=0;x<this.data.length-1;x++) {
      let min = x;
      for (let y=x+1;y<this.data.length;y++) {
        num++;
        if (this.data[min]>this.data[y]) {
          min = y;
        }
      }
      if (x !== min) {
        let tmp = this.data[x];
        this.data[x] = this.data[min];
        this.data[min] = tmp;
      }
    }
    console.log("num:",num);
    // console.log("selectSort:",this.data.toString());
    console.log("selectSort time: ",Date.now() - start);
  }

  this.insertSort = function() {
    let start = Date.now();
    for (let x=1;x<this.data.length;x++) {
      if (this.data[x] < this.data[x-1]) {
        let tmp = this.data[x];
        for (let y=x;y>=0;y--) {
          if (y>0 && this.data[y-1]>tmp) {
            this.data[y] = this.data[y-1];
          } else {
            this.data[y] = tmp;
            break;
          }
        }
      }
    }
    // console.log("insert÷Sort:",this.data.toString());
    console.log("insertSort time: ",Date.now() - start);
  }

  this.fastSortFunc = function (data) {
    if (data.length <= 1) return data;
    let left  =[],right = [];
    let sign = data[0];
    for (let x=1;x<data.length;x++) {
      data[x] <= sign ? left.push(data[x]) : right.push(data[x]);
    }
    return this.fastSortFunc(left).concat(sign,this.fastSortFunc(right));
  }

  this.fastSort = function () {
    let start = Date.now();
    this.data = this.fastSortFunc(this.data);
    console.log("fastSort time",Date.now()-start);
    // console.log("fastSort:",this.data);
  }


}
let a = new TestArr(100000);
// a.paoSort();
// a.selectSort() 
// a.insertSort();
a.fastSort();

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章