树的前序遍历、中序遍历、后序遍历及查找
近日学习了二叉树,之前对其遍历和操作有些疑惑,今天重新打了一遍代码好像悟了些许东西出来,浅浅的讲述一下吧。
首先是中规中矩的树图。
遍历
前序遍历
先上java实现代码
public void preOrder(){
//输出当前节点
System.out.println(this);
//如果当前节点的左子树不为空,则递归调用
if (this.left != null){
this.left.preOrder();
}
//如果当前节点的右子树不为空,则递归调用
if (this.right != null){
this.right.preOrder();
}
}
我们首先来遍历的顺序 1,2,4,5,3,6,8,7
对于当前节点,先输出它自己,随后对其子树按照从左到右的方向进行遍历,因为 1 的左子树是 2 ,2 的左子树是 4,所以输出1,2,4;
由于 2 的左子树输出完毕,所以开始输出它的右子树,得到1,2,4,5;
1 的左子树输出完毕,开始输出右子树,同理,可以得到3,6,8,7;
两个子树输出结果合并起来即是1,2,4,5,3,6,8,7。
中序遍历
也是一段代码
public void infixOrder(){
//如果当前节点的左子树不为空,则递归调用
if (this.left != null){
this.left.infixOrder();
}
//输出当前节点
System.out.println(this);
//如果当前节点的右子树不为空,则递归调用
if (this.right != null){
this.right.infixOrder();
}
}
得到遍历的顺序 4,2,5,1,8,6,3,7
与前序遍历不同的是,中序是先遍历左子树,在输出根节点,再是右子树
顺序是这样子的
对于根节点 1 来说,需要先遍历它的左子树 2,对于 2 来说,需要先遍历它的左子树 4,所以得到 4,2,5;
左子树遍历完毕后遍历根节点 1,得到 4,2,5,1;
然后遍历右子树 3,对于 3 来说,需要先遍历它的左子树 6,对于 6 来说,需要先遍历它的左子树 8,再回头遍历自己 3,最后是右子树 7,所以得到 8,6,3,7;
合并得到 4,2,5,1,8,6,3,7;
后序遍历
还是一段代码
public void postOrder(){
//如果当前节点的左子树不为空,则递归调用
if (this.left != null){
this.left.postOrder();
}
//如果当前节点的右子树不为空,则递归调用
if (this.right != null){
this.right.postOrder();
}
//输出当前节点
System.out.println(this);
}
}
得到遍历的顺序 4,5,2,8,6,7,3,1
后序的遍历规则是先遍历左子树,再遍历右子树,最后是根节点
顺序是这样子的
对于根节点 1 来说,需要先遍历它的左子树 2,对于 2 来说,需要先遍历它的左子树 4,所以得到 4,2,5;
左子树遍历完毕后遍历右子树 3,得到 8,6,7,3;
最后遍历根节点 1,得到4,5,2,8,6,7,3,1;
其实遍历方面不是什么说的上难的知识,只要理解了它的过程,能在脑子中想象出遍历的顺序,就不会有什么问题了。
查找
老规矩,先上代码
和遍历同理,都是一样的顺序,就不多赘述了。把代码看看debug走一遍应该能理解
前序查找
public Node preOrderSearch(int no) {
System.out.println("进入前序遍历");
//比较当前结点是不是
if(this.no == no) {
return this;
}
//1.则判断当前结点的左子节点是否为空,如果不为空,则递归前序查找
//2.如果左递归前序查找,找到结点,则返回
Node resNode = null;
if(this.left != null) {
resNode = this.left.preOrderSearch(no);
}
if(resNode != null) {//说明我们左子树找到
return resNode;
}
//1.左递归前序查找,找到结点,则返回,否继续判断,
//2.当前的结点的右子节点是否为空,如果不空,则继续向右递归前序查找
if(this.right != null) {
resNode = this.right.preOrderSearch(no);
}
return resNode;
}
中序遍历
public HeroNode infixOrderSearch(int no) {
//判断当前结点的左子节点是否为空,如果不为空,则递归中序查找
Node resNode = null;
if(this.left != null) {
resNode = this.left.infixOrderSearch(no);
}
if(resNode != null) {
return resNode;
}
System.out.println("进入中序查找");
//如果找到,则返回,如果没有找到,就和当前结点比较,如果是则返回当前结点
if(this.no == no) {
return this;
}
//否则继续进行右递归的中序查找
if(this.right != null) {
resNode = this.right.infixOrderSearch(no);
}
return resNode;
}
后序遍历
public HeroNode postOrderSearch(int no) {
//判断当前结点的左子节点是否为空,如果不为空,则递归后序查找
Node resNode = null;
if(this.left != null) {
resNode = this.left.postOrderSearch(no);
}
if(resNode != null) {//说明在左子树找到
return resNode;
}
//如果左子树没有找到,则向右子树递归进行后序遍历查找
if(this.right != null) {
resNode = this.right.postOrderSearch(no);
}
if(resNode != null) {
return resNode;
}
System.out.println("进入后序查找");
//如果左右子树都没有找到,就比较当前结点是不是
if(this.no == no) {
return this;
}
return resNode;
}
该文章是我对树的一些理解,后续应该还会有所更改,如有不对之处,还请多多指教。