Java实习多叉树取任意子树_二叉树

树是由一个根结点和若干棵子树构成。

二叉树:每个结点最多两棵子树,是有序的。

满二叉树:二叉树中,所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上。

完全二叉树:在满二叉树中,从最后一个结点开始,连续去掉任意个结点,即是一棵完全二叉树。

二叉树的遍历:前序遍历(根左右),中序遍历(左根右),后序遍历(左右根),层序遍历。


Java实习多叉树取任意子树_结点_02


熟练掌握二叉树的三种遍历递归和非递归的6种实现方法。

宽度优先遍历:对二叉树一层一层的访问,每层结点从左到右依次访问。

二叉树的特例:二叉搜索树,堆,红黑树

二叉搜索树:左子节点总是小于等于根节点,右子节点总是大于等于根节点。

:分为大根堆和小根堆,快速找到最大值或最小值的问题可以用堆来解决。

红黑树:是把树中的结点定义为红黑两种颜色,并通过规则确保从根节点到叶节点的最长路径长度不超过最短路径的两倍。

下面给出二叉树的创建与三种遍历的实现:

二叉树的创建与三种遍历的实现最简单的思想是递归实现。

二叉树的结构体:


Java实习多叉树取任意子树_结点_03


二叉树的创建:


Java实习多叉树取任意子树_结点_04


前序遍历(递归实现):


Java实习多叉树取任意子树_二叉树_05


中序遍历和后序遍历的递归实现也非常简单,在前序遍历代码上简单修改即可,在此不再列出。

三种遍历的非递归方法用到了。之所以要掌握非递归方法,是因为相比于递归,非递归大大提高了效率。在栈中,push代表压栈,top代表取栈顶元素,pop代表弹出栈顶元素。

中序遍历的非递归算法:中序遍历是左根右遍历,具体算法如下:


Java实习多叉树取任意子树_二叉树_06


具体实现如下:


Java实习多叉树取任意子树_# 遍历结构体_07


前序遍历的非递归实现:首先P指针指向根节点,输出根节点的值,压栈,p=p->leftchild,输出P结点的值,压栈,直到P为空,此时栈顶为左边界,因为前序遍历是根左右,现在根左都输出了,令P等于栈顶元素的rightchild,重复上面过程,直到栈空。


Java实习多叉树取任意子树_二叉树_08


难点:后序遍历的非递归实现:后序遍历是左右根,要保证根最后访问,有一种思路是,对任意结点P,让其先入栈,然后若该结点若没有左右孩子,直接打印输出;若有,但是左右孩子之前被访问过,也输出;否则就将该节点的右孩子和左孩子压入栈。这种方法在压栈的时候右孩子先入栈,左孩子再入,保证了输出时左右根。


Java实习多叉树取任意子树_Java实习多叉树取任意子树_09


本文主要参考数据结构相关资料和《剑指offer》,如有错误,欢迎指正。