数据结构与算法

88 阅读2分钟

背景

在各种框架横行的年代如何做一名有价值的不被淘汰的开发人员,底层的知识一定要扎实,框架何其多,但是万变不离其宗,遥想当年,大学时代所有的学科如今依旧是在耳边回响,只不过知识点已经不是那么清晰。现在开始回顾软件工程专业的主要课程。釜底还抽薪呢。

image.png

数组篇

基本概念

image.png

image.png

时间复杂度

  • 顺序排名 image.png
  • 推导 image.png

所有代码执行时间T(n)和代码的执行次数f(n)成正比

T(n)=O(f(n))

n 输入数据的大小或者输入数据的数量
T(n) 一段代码的总执行时间
f(n) 一段代码的总执行次数
O 执行时间T(n) 执行次数f(n)成正比 

时间复杂度规则

使用阶乘和二项式来确定其复杂度

  • O(1)

    console.log()
    function test(){}
    for(let i=0;i<100;i++){}//O(1)
    for(let i=0;i<n;i++){}//O(n)
    ...
    
  • O(logn)

    function test(n){
        let times=0; 
        while(n<17){
            n=n*2;
            times++
        }
        return times;
    }
    //需要用到对数才能解决的代码,比如以2为低16的对数 log2 16=4
    
  • O(n)

    for(let i=0;i<n;i++){}
    while(n>i){}
    //单层循环
    
  • O(nlogn)

    // 复杂度为O(logn)的执行n次
    
  • O(n^2)

    for(){
        for(){
        
        }
    }
    //嵌套循环
    
  • O(n^3)

  • O(n^2n)

  • O(n^!)

数组排序

复杂度

image.png

方法时间复杂度空间复杂度
冒泡
选择
插入
希尔
快排
归并排序
堆排序
计数排序
桶排序
基数排序

实现

  • 冒泡

冒泡排序的基本思想是:每趟从最开始的数比较,知道最后排好。

```
this.array=[10, 4, 2, 8, 6, 1];
 bubbling() {
    for (let i = 0; i < this.array.length; i++) {
      for (let j = 0; j < this.array.length - 1; j++) {
        if (this.array[j] > this.array[j + 1]) {
           [this.array[j], this.array[j+1]]=[this.array[j+1],this.array[j]]
        }
      }
      console.log(this.array);
    }
    return this.array;
  }
  
1.分析
  1.第一躺 最外层的i,104相比,10>410往后移,依次比较,最后[4,2,8,6,1,10],10排成功,开始第二趟;
  2.直到最后[1,2,4,6,8,10];
b.复杂度
  O(n^2)
c.优化
  判断是否交换来减少循环次数
     let isChange=false;
     for (let i = 0; i < this.array.length; i++) {
      for (let j = 0; j < this.array.length - 1; j++) {
        if (this.array[j] > this.array[j + 1]) {
          isChange=true;
           [this.array[j], this.array[j+1]]=[this.array[j+1],this.array[j]]
        }
      }
      if(isChange==false){
         break;
      }
      console.log(this.array);
    }
```
  • 选择排序

选择排序的基本思想是:类似于冒泡排序

```
    selecting(){
        for(let i=0;i<this.array.length;i++){
            for(let j=0;j<this.array.length;j++){
                if(this.array[i]<this.array[j]){
                    [this.array[j], this.array[j-1]]=[this.array[j-1],this.array[j]];
                }
            }
        }
        return this.array;
    }
```
  • 插入排序

插入排序的基本思想是

```
insert(){
    for(let i=0;i<this.array.length;i++){
        for(let j=i;j<this.array.length;j--){
            if(this.array[j-1]>this.array[j]){
                [this.array[j], this.array[j-1]]=[this.array[j-1],this.array[j]]
            }
        }
    }
}
```
  • 希尔排序 缩小增量排序

希尔排序的基本思想是:对插入排序的优化,先把要排序的记录分成若干子序列,对子序列进行插入排序,最后对整个序列进行插入排序。

```
 let len = arr.length,
        temp,
        gap = 1;
      while (gap < len / 2) { 
        gap = gap * 2 + 1;
      }
      for (gap; gap > 0; gap = Math.floor(gap / 2)) {
        for (let i = gap; i < len; i++) {
          temp = arr[i];
          let j = i - gap;
          for (; j >= 0 && arr[j] > temp; j -= gap) {
            arr[j + gap] = arr[j];
          }
          arr[j + gap] = temp;
      }
    };
  return arr;
```
  • 归并排序

归并排序的基本思想是:分而治之

  • 快速排序

快速排序的基本思想是

  • 堆排序

堆排序的基本思想是

  • 计数排序

计数排序的基本思想是

  • 桶排序

桶排序的基本思想是

  • 基数排序

基数排序的基本思想是

递归

小结

任何语言排序也是最基本的。