引言
二叉树的Java实现
之前有两篇博客是利用C++实现了二叉树的各种常用操作,这里提供二叉树常用操作的Java实现。
其实如果不追求空间最小,那么就不必非要采用数组实现,而是直接利用Java中的Stack去实现。只要利用Stack后进先出的特性,就可以很好地实现各种非递归算法。
1.二叉树节点的定义
考虑到拓展性,当然要使用范型来定义。
|
|
2.二叉树的创建
下面提供一个利用广义表创建二叉树的方法,比如利用”A(B(D,E(G)),C(F(,H)))”创建二叉树.
|
|
为了进行测试,在StackOverflow中找到一个可以打印出二叉树形状的方法,如下所示:
|
|
测试依据广义表创建二叉树的代码如下:
|
|
结果如下:
3.前序遍历
所谓前充遍历,就是最先访问根结点,之后是左子结点,最后是右子结点。
递归算法太简单,就不多说了。对于非递归算法 ,由于是先访问左子结点,后访问右子结点,而Stack的规则是先进后出,所以只要让右子节点先进入Stack即可。
|
|
4.中序遍历
所谓中序遍历,即结点的访问顺序为:左孩子–>根结点–>右孩子。
递归算法也是极为简单,不提也罢。对于非递归算法,由于需要先遍历左孩子,为了达到这个目的,就需要借助另一个Stack的帮助,以记录这是第几次访问当前结点,如果是第一次,就需要仍然把它放回去,并且将它的左孩子push进入stack,当然,此时对应stack中的标记也要修改。如果是第二次,则可以打印它,并且将它的右孩子(如果存在)加入到Stack中。
|
|
5.后序遍历
后序遍历的结点遍历顺序为:左孩子–>右孩子–>根结点.
类似地,对于非递归算法,仍然需要符号Stack的帮助,并且要进行再次判断,如果是第一次访问到这个结点,则暂时不能打印它,而是要将它的左孩子push到Stack中,当然,flagStack中的标记也要相应改变;如果是第二次访问到这个结点,则仍然还不能打印它,而是要将它的右孩子push到Stack中,同时flagStack要相应地改变。
只有第三次访问到这个节点,才能打印它。
|
|
6.层次遍历
层次遍历其实就是严格按照FIFO的顺序进行遍历,所以需要使用队列.
Java中入队方法是Queue.offer();出队方法是Queue.poll();
|
|
需要注意的是,左孩子和右孩子进入队列的顺序可调换.
7.求二叉树深度
其实求深度很简单,只要采用某种方式遍历即可,此处采用最简单的前序遍历.此处定义根节点深度为1,依次往下:
|
|
8.遍历测试
利用之前创建的二叉树进行各种遍历方式的测试,测试代码如下所示:
|
|
结果如下所示: