- 该合辑为笔者自b站自学的“C++数据结构与算法”课程学习记录,旨在将重要的学习要点、思考内容与部分代码进行记录,以便后续自行翻看,亦可给其他读者带来一些参考
- 内容基于笔者自身的理解或感悟,可能存在不妥当或是错误之处
- 系统环境:Win10,Visual Studio 2019
目录
递归(branching structure) vs 循环(looping structure)
Recursion 递归
解决问题更小规模的版本,通过调用函数自身的方式来解决实际问题,其编程需要多加谨慎,在程序设计时即要考虑要有趋向结束条件的趋势,否则可能会爆栈
base case 终结条件
general case 一般条件
stack overflow 栈溢出
程序运行时的活动记录压入runtime stack(运行时栈),如果递归语句嵌套太多或逻辑不合理,可能会造成栈溢出,程序报错
divide and conquer 分治法
先将问题分解,再对子问题进行求解,最终将子问题结合(combine),从而实现大问题的解决,例如需求是找到两个int数组结合后的中位数,不采用分治法可能会使时间复杂度达到O(n),而采用分治法可以将其优化到O(logn)
递归(branching structure) vs 循环(looping structure)
递归的优点:
(1)一般情况下语句较为简洁
(2)因其大都采用 if,else结构,故逻辑清晰易于理解,代码可读性较强
递归的缺点:
(1)一般效率稍低,对于内存的空间消耗更大
(2)设计不慎可能会导致栈溢出
基于以上,在以下条件具备其一时,可以考虑使用递归算法:
(1)能实现需求的前提下,递归的嵌套浅,对内存的消耗不太大
(2)使用循环结构和递归实现上效果差不多,因此采用递归使代码简洁、易读
Backtracking 回溯
在遇到回溯条件时,退回到程序先前的状态,并采用另一种策略路线来尝试达到最终递归终点
例如8皇后问题、迷宫问题可以采用回溯法来解决
拿八皇后问题来举例,国际象棋中皇后可以攻击到其所在格子内八个方向(上下左右,包括四个斜角) 内的敌人,现有8位皇后均要布置在8×8的国际象棋棋盘内,要求任意一个皇后都不可以被其他皇后有攻击到的可能性,讨论该如何放置这八位皇后
采用回溯的基本思想是,首先在第一列第一行放置皇后,再尝试在第二列第一行放置皇后,如冲突则在第二行、第三行(以此类推......)放置,再在第三列尝试(以此类推......),注意到在放置第五位皇后时,一列中的八个位置均不可取,故回溯到上一位(第四位皇后),将其改到另一个位置后继续尝试
The End