效果演示与分析
二叉树是绘图中的经典算法,通过这种算法,可以画出很多漂亮的图案:
下面是绘制二叉树的过程:
上面图中的二叉树里,其实是由很多个小的两条边的树杈组成的:
并且每个小树杈都在上一层的树杈末端:
所以我们把问题分解成两个解决步骤:
1、先画一个树杈,并封装成函数,方便重复使用。
2、在树杈的末端,画下一层的树杈,也就是调用刚才封装的函数。
画一个树杈
画一个树杈的代码很简单,不过这里要注意的是:因为在一条线的末端,我们要再画下一层的树杈,下一层画完之后,才回来继续本层树杈的线条,所以下一层的树杈绘制不能影响本层绘制。这就要求我们封装的函数满足一个特点:进入函数的时候,画笔是什么状态,函数结束时,画笔必须还是什么状态。
看下面的代码:
这段代码很好理解,那么接下来就要开始嵌套画树杈了。
画下一层的树杈
在画一边树杈的时候,我们在forward之后,调用一次tree,这样就可以绘制出下一层的树杈。因为我们在写上面的树杈的时候,特意还原了画笔的状态,所以中间加入tree()函数不影响原本的绘制。
原理是这样,似乎……没有错。不过单单这样写的话,依然画不出来。同学们可以想到为什么吗?
递归
像这样在函数内调用自己本身的写法叫做递归,是计算机编程中一个分水岭性质的算法。
编程界有一句名言:迭代的是人,递归的是神。出自L Peter Deutsch。递归,其实才是计算机算法编程的入口。
回过头来再看上面的代码,在画第一个树杈分支的时候递归调用tree(),画下一层,下一层再调下一层,再下一层……子子孙孙无穷尽也。形成一个死循环。
所以写递归有一个非常重要的注意点:边界条件,也就是递归在满足什么条件的时候不再继续。
上代码:
原理如上,更复杂和好看的二叉树请同学们自己研究,画的时候注意一个重点:进入函数的时候,画笔是什么状态,函数结束的时候就还得是什么状态。