写给大家看的算法书-笔记

2019-10-16  本文已影响0人  三文治z

注:个人读《写给大家看的算法书》的粗略笔记,和看的一些博客的总结

一、数据结构

常用的数据结构 Part One

1.链表

2.数组

3.堆栈

4.队列(等待队列)

5.树(树木的结构)

常用的数据结构 Part Two

1.堆栈(STACK)

堆栈管理数据的两种操作:

2.队列(QUEUE)

-最先输入的数据最先输出
这种数据管理方式被称为 FIFO(First In, First Out)

3.链表

4.单向链表(只能从前到后检索数据)

5.双向链表(可以 从前到后 也可以 从后向前 检索数据)

6.树

7.二叉树(Binay tree)

8.图

二、算法

例题

1.计算 1~N 的整数的总和

1~2:1+2
1~3:1+2+3
1~4:1+2+3+4
1~5:1+2+3+4+5
通式:1+2+3+......+(N-1)+N

function fn(n) {
    let sum = 0;
    for(let i = 0;i <= n; i++){
        sum += i
    }
    return sum
}
fn(5);     // 15

2.斐波那契数列(兔子数列)

1,1,2,3,5,8,13,21,34,55.......
求第 N 个数字

1) 递归:
function Fibonaci(n) {
    if(n==1 || n==2)  { return 1 }
    return Fibonaci(n-1) + Fibonaci(n-2)
}
2) 优化:尾递归(尾部调用自身)

把之前已经计算好的结果以参数的形式传递过去

function Fibonaci(n, ret1=1, ret2=1) {
    if(n==1 || n==2)  { return ret2 }
    return Fibonaci(n-1, ret2, ret1+ret2)
}
3) for循环版
function Fibonaci(n) {
    if(n==1 || n==2) { return 1 }
    let ret1 = 1, ret2 = 1
    for(let i = 2; i < n; i++){
        [ ret1, ret2 ]  =  [ ret2, ret1+ret2 ]
    }
    return ret2
}

排序(以下均为升序)

1.桶排序

const arr = [ 8, 3, 5, 9, 2, 3, 0, 8 ]
 function BucketSort(list) {
    // 创建 [0, 0, ..., 0] 的数组,长度为10-----数组长度要 >(大于) 需排序数组元素的最大值
    const newList = Array.from({length:10}).fill(0);
    list.forEach(el => newList[el] += 1);      // 把数组元素记录在 newList 上

    return newList.reduce((pre, el, index) => {    // 展开数组
        for(let i=0; i<el; i++){  
            pre.push(pre)
        }
        return pre
   }, [] )
}

2.选择排序

选择最小值(最大值)

function SelectionSort(list) {
    list = [...list];     // 最好不要对原数组操作
    const newList = [];   // 创建待返回的空数组
    while(list.length) {  // 循环,当 list.length === 0 时,表示处理完毕
        let min = list[0];  // let min = Infinity; 设最小值无穷大 或者 等于 list 中的任意位置都可
        let minIndex;       // 记录下最小值下标
        list.forEach((el, index) => {     // 对 list 循环,查找当前 list 最小值
          if(el <= min) {
            min = el;
            minIndex = index;
          }
        });
        newList.push(list[minIndex]);     // 将 最小值下标 对应的值 push 进数组
        list.splice(minIndex, 1);         // 从list内删除这个值
      }
      return newList
    }

3.冒泡排序

核心是:比较相邻的两个元素的大小关系,如果大小关系和排序顺序相反,则交换这两个元素的位置

function BubbleSort1(arr){
  var i,j,temp;
  for(i=0; i<arr.length-1; i++){
    for(j=i+1; j<arr.length; j++){
      if(arr[i] > arr[j]){
        temp = arr[j];
        arr[j] = arr[i];
        arr[i] = temp;
      }
    }
  }
  return arr;
}

改良:将小的数字如同气泡一样慢慢的浮上表面

function BubbleSort(arr){
  for(let i = 0; i < arr.length-1; i++) {
    for(let j = arr.length-1; j > i; j--) { // j为从后往前循环
      if(arr[j] < arr[j-1]) {           // 后面的小于前面的,则交换
        [ arr[j-1], arr[j] ] = [ arr[j], arr[j-1] ]
      }
    }
  }
  return arr;
}

补充:不使用中间变量,互换两个元素,原型如下:

var a = 10; // 第一个元素
var b = 5;  // 下一个元素
if (a > b) {
  a = a + b; //  a(15) = 10 +5;
  b = a - b; //  b(10) = 15 - 5;
  a = a - b; //  a(5) = 15 - 10;
}
// a = a+b 这个得到的是 a 和 b 的和;也就是这一步运行之后当前的a的值就是 a,b 之和。
// b = a-b,既然 a 是他们两个的和,那么 a-b 得出的肯定是最初的a的值;这一步运行之后,b 的只就是原始 a 的值;
// a = a-b,既然 b 是原始 a 的值,a 是原始 a 和原始 b 的和,那么差值肯定就是原始 b的值。

通过es6,可以实现同样的效果:

let arr1 = [ 1, 3 ];
[ 1, 3 ]=[ 3, 1 ];
console.log(arr1);   // => [3, 1]

4.插入排序

function InsertSort(arr) {
  for (let i = 1; i < arr.length; i++){
    for (let j = i; j > 0; j--){
      // 当前值和之前的每个值进行比较,发现有比当前值小的值就进行重新赋值
      if(arr[j] < arr[j-1]){
        [ arr[j-1],  arr[j] ] = [ arr[j],  arr[j-1] ]
      }
    }
  }
  return arr;
}

5.快速排序

快速排序的原理:选择一个基准值,一般选择数组的一个值,遍历数组,大的放右边,小的放左边,一样大的放中间。利用递归重复对大的数组和小的数组进行拆分,最后得出排序后的数组。

function QuickSort(arr) {
  if(arr.length < 2) {
    return arr;
  } else {
    const pivot = arr[0];   // 基准值
    const pivotArr = [];    // 一样大的放中间
    const lowArr= [];       // 小的放左边
    const hightArr = [];    // 大的放右边
    arr.forEach(current => {
      if(current === pivot) pivotArr.push(current);
      else if(current > pivot) hightArr.push(current);
      else lowArr.push(current);
    })
    return quickSort(lowArr).concat(pivotArr, quickSort(hightArr));
  }
}
上一篇下一篇

猜你喜欢

热点阅读