环路复杂度到底在量什么
McCabe 环路复杂度可以理解成程序控制结构的复杂程度。分支越多,独立路径越多,测试时需要考虑的路径也越多。
考试里它通常和控制流图一起出现,问 V(G) 等于多少,或者问至少需要多少条独立路径。
最常用的三个公式
环路复杂度有几种等价算法。题目给控制流图时,常用 V(G)=E-N+2;题目给判定节点数时,常用 V(G)=判定节点数+1。
如果图上能数区域数,也可以用区域数来判断。不同方法算出来应该一致,如果不一致,说明图数错了。
边点法V(G) = E - N + 2,其中 E 是边数,N 是节点数
判定法V(G) = 判定节点数 + 1
区域法V(G) = 控制流图中的区域数
判定节点怎么数
if、while、for、case 分支这些会改变控制流的结构,通常都要关注。最简单的题里,一个二分支判断就是一个判定节点。
但不要把普通顺序语句也算成判定节点。赋值、计算、输出这类顺序动作不会增加独立路径。
| 结构 | 是否通常增加复杂度 | 说明 |
|---|---|---|
| 顺序语句 | 否 | 不产生新分支 |
| if 判断 | 是 | 产生分支路径 |
| while/for 循环 | 是 | 有进入循环和退出循环路径 |
| case 多分支 | 是 | 按分支结构增加复杂度 |
一个不用画图的小例子
假设一段程序里有 3 个 if 判断,没有其他复杂分支。用判定法可以直接算:V(G)=3+1=4。
这表示至少要设计 4 条独立路径测试,才能覆盖这段程序的基本路径集合。注意它不是说只测 4 个输入就一定万无一失,而是基本路径测试的最低提示。
小例子
判定节点数 = 3。
环路复杂度 V(G) = 3 + 1 = 4。
基本路径测试至少关注 4 条独立路径。
常见失分点
第一,把节点数和边数数反。用 E-N+2 时,E 是边,N 是节点,不要倒过来。
第二,把每一行代码都当节点。控制流图里的节点不是简单等于代码行数,要看控制结构怎么抽象。
第三,忘记 +1。用判定节点法时,很多人只写判定节点数,少了最后的 +1。