算法
定义
- Algorithm
 - 一个有限指令集
 - 接受一些输入(有些情况下不需要输入)
 - 产生输出
 - 一定在有限步骤之后终止
 - 每一条指令:有充分明确的目标,不可以有歧义;在计算机能处理的范围之内;描述应不依赖于任何一种计算机语言以及具体实现
 - 所以学习算法最重要的是学习算法的设计过程(算法思维),而不是算法本身,理论要与实践相结合
 - 等到算法能力掌握到一定程度的时候,再去学习复杂度算法这些
 - 数据结构的价值,在于其思维逻辑结构层面的价值
 
五个重要特性
- 有穷性
 - 确定性
 - 可行性: 可以通过基本运算有限次执行来实现
 - 有输入
 - 有输出
 
// 示例: 选择排序伪代码
void SelectionSort (int List[], int N) {
    for(int i = 0; i < N; i++) {
        // 从List[i] 到 List[N-1] 中找最小元,并将其位置赋值给MinPosition
        MinPostion = ScanForMin(List, i, N-1)
        // 将未排序部分的最小元换到有序部分的最后位置
        Swap(List[i], List[MinPosition])
    }
}
好的算法
指标:
空间复杂度S(n) Space
- 写成的程序在执行时占用存储单元的长度
 - 长度往往与输入数据的规模n有关
 
事件复杂度T(n) Time
- 写成的程序在执行时耗费时间的长度
 - 长度往往与输入数据的规模n有关
 - 机器运算加减法要比乘除法要快很多
 
分析一般算法的效率:
- 最坏情况复杂度Tworst(n)
 - 平均复杂度Tavg(n) Tavg(n) <= Tworst(n)
 - 所以一般就分析最坏情况复杂度
 
复杂度的渐进表示
最大子列和问题
// 给定N个整数的序列{ A1,... An}, 求函数f(i, j) = max{0, ∑ k=i j Ak} 的最大值
排序算法
二分法
void HalfSort(int List[], int N, int X) {
    // 取中间值, Min , Max
    Min = 0
    Max = N - 1
    Middle = (Max + Min)/2
    while(Min <= Max) {
        if (List[Middle] < X) {
            Min = Middle
            Middle = (Max + Min)/2
        } else if (List[Middle] > X) {
            Max = Middle
            Middle = (Max + Min)/2
        } else {
            return Middle
        }
    }
    // 没找到
    return -1
}
// 空间复杂度 S(n) = O(1)
// 时间复杂度:T(n) 最好 O(1), 最坏: C log(n)
快速排序算法
- 选定基准值
 - 分区(小于基准值放左边,大于基准值放右边);
 - 对于左边与右边的分区递归进行分区(partition);
 - 第一次轮n次;第二次轮n-1次,,,联想到二叉树,树的高度越低效率就越高
 
// 选择排序
console.time(1);
let arr = [8,3,24,45,33,23,41,54,33,22,7,7,4,9,0,110];
let sortedArr = [];
function chooseSort(arr) {
  if(arr.length == 0) {
    return
  }
  for(let i = 1, len = arr.length; i < len; i++) {
    if(arr[i] <= arr[0]) {
      let temp = arr[0];
      arr[0] = arr[i];
      arr[i] = temp;
    }
  }
  sortedArr.push(arr.splice(0,1)[0]);
  chooseSort(arr);
}
// chooseSort(arr);
// console.log(sortedArr);
// arr.sort((a,b) => {
//   return a-b;
// })
// console.log(arr)
console.timeEnd(1);
// 快速排序
console.time(2);
let arr = [8,3,24,45,33,23,41,54,33,22,7,7,4,9,0,110];
function quickSort(arr) {
  if(arr.length < 2) {
    return arr;
  }
  let basic = arr[0];
  let left = [];
  let right = [];
  for(let i = 1, len = arr.length; i < len; i++) {
    if(arr[i] < basic) {
      left.push(arr[i])
    }
    if(arr[i] >= basic) {
      right.push(arr[i])
    }
  }
  return quickSort(left).concat([basic]).concat(quickSort(right));
}
console.log(quickSort(arr));
console.timeEnd(2);
快排优化
快速选择算法(只是想找排名第K个的元素)
当我们需要快速找到一个元素X,并且使得小于X的元素数量是K-1个时,那X就是我们要查找的排名第K位的元素了,可以用partition;
- 堆排序
 - 归并排序
 其它趣味算法
红黑树
- 哈希表
 
内排序
外排序
查找算法
搜索算法
- 深度优先搜索
 - 广度优先搜索
 
描述算法的常用工具 - 程序框图(流程图)


