**一、排序算法**
1. 冒泡排序(Bubble Sort):
- 重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。
- 时间复杂度:O(n²),空间复杂度:O(1)。
2. 选择排序(Selection Sort):
- 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。
- 时间复杂度:O(n²),空间复杂度:O(1)。
3. 插入排序(Insertion Sort):
- 对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
- 时间复杂度:O(n²),空间复杂度:O(1)。
4. 归并排序(Merge Sort):
- 采用分治的思想,将数列分成两部分,分别进行排序,然后将两个有序数列合并。
- 时间复杂度:O(n log n),空间复杂度:O(n)。
5. 快速排序(Quick Sort):
- 从数列中挑出一个元素,称为“基准”,重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
- 时间复杂度:O(n log n)(平均情况),最坏情况为 O(n²),空间复杂度:O(log n)(平均情况),最坏情况为 O(n)。
**二、搜索算法**
1. 顺序搜索(Sequential Search):
- 从列表的第一个元素开始,逐个检查每个元素,直到找到目标元素或遍历完整个列表。
- 时间复杂度:O(n)。
2. 二分搜索(Binary Search):
- 适用于已排序的列表。每次将搜索区间分成两部分,根据目标元素与中间元素的大小关系确定下一步搜索的区间。
- 时间复杂度:O(log n)。
**三、动态规划**
1. 基本思想:
- 将问题分解成多个子问题,通过求解子问题并保存结果,避免重复计算,最终得到原问题的解。
2. 步骤:
- 定义状态:确定问题的状态表示,通常是一个或多个变量。
- 建立状态转移方程:根据问题的性质,找到状态之间的关系,建立状态转移方程。
- 确定初始状态和边界条件:确定问题的初始状态和边界条件,以便从这些状态开始进行递推求解。
- 计算结果:按照状态转移方程,从初始状态开始逐步计算,直到得到最终问题的解。
**四、贪心算法**
1. 基本思想:
- 在每一步选择中都采取当前状态下的最优决策,希望通过局部最优选择达到全局最优解。
2. 特点:
- 通常用于求解具有最优子结构性质的问题。
- 不一定能得到全局最优解,但在某些情况下可以快速得到一个较好的近似解。
**五、回溯算法**
1. 基本思想:
- 尝试所有可能的解决方案,当遇到不满足条件的情况时,回溯到上一步,尝试其他可能的选择。
2. 应用场景:
- 解决组合问题、排列问题、子集问题等。
**六、图算法**
1. 深度优先搜索(Depth-First Search,DFS):
- 从图的某个顶点出发,沿着一条路径尽可能深地探索图,直到无法继续前进时,回溯到上一个顶点,继续探索其他未访问的路径。
- 时间复杂度:O(V + E),其中 V 是顶点数,E 是边数。
2. 广度优先搜索(Breadth-First Search,BFS):
- 从图的某个顶点出发,依次访问其所有相邻顶点,然后再访问这些相邻顶点的相邻顶点,直到访问完所有顶点。
- 时间复杂度:O(V + E)。
3. 最短路径算法:
- Dijkstra 算法:用于求解单源最短路径问题,即给定一个图和一个源顶点,求从源顶点到其他所有顶点的最短路径。
- Floyd-Warshall 算法:用于求解任意两个顶点之间的最短路径。
4. 最小生成树算法:
- Prim 算法:从一个任意的顶点开始,每次选择一条权值最小的边,将其连接的顶点加入到生成树中,直到所有顶点都被加入。
- Kruskal 算法:按照边的权值从小到大的顺序选择边,只要不形成回路就将其加入到生成树中,直到所有顶点都被连接。
**七、树算法**
1. 二叉树遍历:
- 前序遍历:根节点 -> 左子树 -> 右子树。
- 中序遍历:左子树 -> 根节点 -> 右子树。
- 后序遍历:左子树 -> 右子树 -> 根节点。
- 层次遍历:从上到下,从左到右依次访问每一层的节点。
2. 二叉搜索树:
- 特点:左子树的所有节点值小于根节点值,右子树的所有节点值大于根节点值。
- 操作:插入节点、删除节点、查找节点等。
3. 平衡二叉树:
- 如 AVL 树、红黑树等,通过旋转等操作保持树的平衡,保证查找、插入、删除等操作的时间复杂度为 O(log n)。