知识体系第二遍回顾补充--②冒泡算法

注: 时间复杂度: 完成一个程序所需要的时间;

          一套图 搞懂“时间复杂度”:O(1): 常量; O(logn): 对数; O(n):线性; O(n^2):指数型;

     空间复杂度: 完成一个程序所需要的内存/变量;

标准:数组内部数字的升序排列;

思想 空间复杂度    
循环比较O(n^2) O(n^2) 冒泡排序:你比我小,我就要和你换,大值往上 选择排序:你比我小,我就要和你换,小值往下
分而治之O(nlogn) O(logn) 快速排序:取基值,左小右大,递归调,concat连 归并排序:一直中分,用slice,合并比较终用shift
无序插有序O(n^2) O(1) 插入排序:你比我大,你就后移,找到最后一个大值,插入 二分法排序:找到第一个大值,大值自身及后面都后移,插入
    arr.sort((a,b)=>a-b)  

1.冒泡排序: 两两比较,如果前一个比后一个大,则互换位置,每次循环比较后,最后一个永远是最大的,下一轮比较,它就不参与了。

口诀:一层减1,二层减i减1

时间复杂度:(n-1)*(n-i-1)=n^2

点击查看代码
function sort(array){
    for(var i = 0; i < array.length - 1; i++){
      for(var j = 0; j<array.length - i -1; j++){ //最后一个不参与排序
        if(array[j] > array[j+1]){
          var smap = array[j]; //把大值赋值给一个变量
          array[j] = array[j+1]; //把小值前移
          array[j+1] = smap; //把大值后移
        }
      }    
    }
      return array;
}

一共比较了 1 + 2 + 3 + ... + (array.length-1) 次比较。

2. 快速排序: 取基准,左小右大,做递归;两个坑儿要记牢,长度小(于)1要返回,splice截取后要取[0]; (20210627总结)

    arr.splice(index,num,items); 返回被截取的数组

    Math.floor(num); 对浮点数向下取整。

    时间复杂度:O(nlogn)

点击查看代码
function quickSort(array){
    if(array.length <= 1){// 避免进入递归死循环,此行必加
      return array;
    }  

    //var middleIndex = Math.floor(array.length / 2);
    //var middle = array.splice(middleIndex,1)[0]; //获得中间数值
    // 20210615 新写法
       var middle = array.splice(0,1)[0];// 直接截取第一个得了,并且用splice函数截取出原数组,简单直接,因为怎么都是顺序一遍
       var left = [];
    var right = [];
    for(var i = 0; i < array.length; i++){
      if(array[i] < middle){
        left.push(array[i]); //把小于中间数的放到左边的数组里
      }eles{
        right.push(array[i]); //把大于中间数的放到右边的数组里面
      }
    }
    return quickSort(left).concat([middle],quickSort(right)); //进行递归调用
}

3. 插入排序: 设定有序数列和无序数列,把无序数列中的项插入到有序数列中,在有序数列的内循环中采取移动赋值的方式达到目的。

适合小数据量排序(<1000)

时间复杂度:O(n^2)

空间复杂度:O(1)

点击查看代码
// 插入排序,无序数列依次插入有序数列
function insertSort(array = []){
  for(let i = 1;i < array.length; i++){// 默认第一项已经排好序了
    let temp = array[i];// 无序数列第一项
    let j = i - 1;
    while(j>=0 && array[j] > temp){// (从后往前扫描)比我大,你就后移
      array[j+1] = array[j];
      j--;
    }
    // 找到自己位置了,我就插入
    array[j+1] = temp;
  }
  return array;
}

4. 二分法排序:在插入排序的基础上进行的优化,在已排序数列中,找到第一个比待插入项大的值

点击查看代码
// 二分算法:在插入排序的基础上进行的优化,在已排序数列中,找到第一个比待插入项大的值
function binaryInsertSort(arr = []){
  for(let i = 1;i < arr.length;i++){
    let temp = arr[i];
    let left = 0;
    let right = i-1;
    // 1. 二分法找第一个大值的位置
    while(left<=right){
      // 中间值
      let middle = parseInt( (right+left)/2 );
      if(temp < arr[middle]){// 数组元素值
        right = middle - 1;
      }else {
        left = middle + 1;
      }
    }

    // 2. 整体后移,从当前项的前一项开始,依次后移
    for(let j = i - 1;j >= left;j--){
      arr[j+1] = arr[j];
    }
    // 3. 找到位置,插入
    arr[left] = temp;
  }
  return arr;
}

5. 选择排序: 把未排序列表中最小(大)的数,排在首位,再把剩余未排序列表中最小(大)的数,排在排序列表的后面,依据索引来排序。

前面的是最小的,和冒泡排序的逻辑是相反的,是把未排序中最小的往前移

点击查看代码
// 选择排序:把未排序中的最小值往前移
function selectionSort(arr = []){
  for(let i = 0;i < arr.length;i++){
    let minIndex = i;// 初始化的最小值
    let temp = arr[i];// 1. 暂存变量
    for(let j = i+1;j < arr.length;j++){
      if(arr[j] < arr[minIndex]){// 2. 既然你比我小,我就要把最小的称号给你喽
        minIndex = j;
      }
    }
    // 3. 最终找到了未排序中的最小值的索引,那就替换吧
    arr[i] = arr[minIndex];
    arr[minIndex] = temp;
  }
  return arr;
}

6. 归并排序:分而治之的思想;

先分解,分到不能再分,return递归合并;后合并,合到其一为空,起变量,用shift,concat连。(20210627总结口诀)

时间复杂度:O(nlogn)

和快速排序很像

点击查看代码
// 归并排序:分而治之的思想
function mergeSort(arr = []){
  // 1. 先分解
  function sort(arr = []){
    if(arr.length <= 1){ return arr } // 分到不能再分为止

    let mid = Math.floor(arr.length/2);
    let left = arr.slice(0,mid);
    let right = arr.slice(mid);
    return merge(sort(left),sort(right));
  }

  // 2. 再合并
  function merge(left = [],right = []){
    let temp = [];
    while(left.length && right.length){// 直到某个数组为空为止,while挺好用
      if(left[0] < right[0]){
        temp.push(left.shift());// 关键一步,把小值剔除(shift)原数组
      }else {
        temp.push(right.shift());
      }
    }
    return temp.concat(left,right);
  }

  return sort(arr);
}

7. 排序:

无法保证时间和空间复杂度(取决于具体表现)

arr.sort((a,b)=> a-b ); //升序排列;b-a// 降序排列;

口诀:顺升,逆降,改变原数组; 

参考链接:

    sort的用法 : 原理,原地排序

8. 希尔排序[todo]

 

参考链接:

    js 实现排序算法 -- 希尔排序(Shell Sort)

    十大经典排序算法(动图演示)

 

 

参考链接:

JS实现插入排序

归并排序算法及其JS实现 :分而治之思想,归并思想

 

posted @ 2018-07-08 14:27  惊沙男孩  阅读(124)  评论(0)    收藏  举报