算法笔记(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();

 

 

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