java 递归二叉树遍历二叉树_Java数据结构之二叉树的基本介绍与递归遍历

二叉树的基本概念:

正如我们所了解的,树是有很多中形态,但是我们规定,形如每个节点最多只能有两个子节点的一种形如称为二叉树。我们将二叉树中该节点的两个子节点分别称作为:左孩子节点和右孩子节点。该节点称为他们的双亲节点。

二叉树的结构示意图如下:

baba5988fad0adc01e0b7acdaf195ddc.png

在二叉树的树状结构中,有两种特殊的二叉树值得我们关注。

首先如果该二叉树的所有叶子节点都在最后一层,并且节点的总数=2^n-1,n为层数(相当于,该二叉树最底层没有空余的位置),这样的二叉树我们称为满二叉树。

满二叉树的结构示意图如下:

5032b1569dca74fbaf2d47ab5859613a.png

如果该二叉树的所有叶子节点都在该树的最后一层或倒数第二层,并且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,这样的二叉树我们称为完全二叉树。

完全二叉树的结构示意图如下:

4881ee546064ca586e88e78ad84b39f9.png

由以上两个图我们可以了解到,满二叉树是完全二叉树的一种。

二叉树的遍历操作:

二叉树的遍历操作主要有三种:先序遍历,中序遍历,后序遍历。

(1).先序遍历:先输出父节点,再遍历左子树,再遍历右子树。

(2).中序遍历:先遍历左子树,再输出父节点,再遍历右子树。

(3).后序遍历:先遍历左子树,再遍历右子树,再输出父节点。

结论:看输出父节点的顺序,就可以确认到底是先序,中序还是后序。

下面我将用一个示意图来表示先序,中序,后序的执行过程。

36c7a4aed7c009e757567de5c464274c.png

下面我会通过代码来具体描述二叉树遍历的执行过程,具体的详解再代码的注释中说明:

package tree;

public class BinaryTreeDemo {

public static void main(String[] args) {

// TODO Auto-generated method stub

//创建二叉树,这里面采用手动的创建,后面的讲解中会使用递归创建

HeroNode root = new HeroNode(1, "java");

HeroNode node2 = new HeroNode(2, "c");

HeroNode node3 = new HeroNode(3, "c++");

HeroNode node4 = new HeroNode(4, "python");

HeroNode node5 = new HeroNode(5, "c#");

BinaryTree binary = new BinaryTree();

//手动的创建二叉树,得到的二叉树与我们示意图中的二叉树相同

root.setLeft(node2);

root.setRight(node3);

node3.setLeft(node4);

node3.setRight(node5);

//把上述创建的二叉树与我们定义的二叉树的类相关联

binary.setRoot(root);

binary.preOrder();

System.out.println("=======");

binary.infixOrder();

System.out.println("=======");

binary.postOrder();

}

}

class BinaryTree{

//私有化一个root节点

private HeroNode root;

public HeroNode getRoot() {

return root;

}

//获取root节点

public void setRoot(HeroNode root) {

this.root = root;

}

//先序遍历

public void preOrder(){

if(this.root!=null){

this.root.preOrder();

}else{

System.out.println("二叉树为空,无法创建!");

}

}

//中序遍历

public void infixOrder(){

if(this.root!=null){

this.root.infixOrder();

}else{

System.out.println("二叉树为空,无法创建!");

}

}

//后序遍历

public void postOrder(){

if(this.root!=null){

this.root.postOrder();

}else{

System.out.println("二叉树为空,无法创建!");

}

}

}

//先创建节点

class HeroNode{

private int no;

private String name;

private HeroNode left; //默认为null

private HeroNode right; //默认为null

public HeroNode(int no,String name){

this.no = no;

this.name = name;

}

public int getNo() {

return no;

}

public void setNo(int no) {

this.no = no;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public HeroNode getLeft() {

return left;

}

public void setLeft(HeroNode left) {

this.left = left;

}

public HeroNode getRight() {

return right;

}

public void setRight(HeroNode right) {

this.right = right;

}

@Override //代表覆盖方法,重载

public String toString() {

return "HeroNode [no=" + no + ", name=" + name + "]";

}

//节点的先序遍历,中序遍历,后续遍历必须定义在这里,因为在二叉树执行递归的时候,只能通过这里找到该方法,否则执行不了。

public void preOrder(){

System.out.println(this); //首先,输出父节点

if(this.getLeft()!=null){ //如果左孩子存在的话,那么递归左子树

this.getLeft().preOrder();

}

if(this.getRight()!=null){ //如果右孩子存在的话,那么递归右子树

this.getRight().preOrder();

}

}

public void infixOrder(){

if(this.getLeft()!=null){ //如果左孩子存在的话,那么递归左子树

this.getLeft().infixOrder();

}

System.out.println(this); //输出父节点

if(this.getRight()!=null){ //如果右孩子存在的话,那么递归右子树

this.getRight().infixOrder();

}

}

public void postOrder(){

if(this.getLeft()!=null){ //如果左孩子存在的话,那么递归左子树

this.getLeft().postOrder();

}

if(this.getRight()!=null){ //如果右孩子存在的话,那么递归右子树

this.getRight().postOrder();

}

System.out.println(this); //输出父节点

}

}

上述代码我们最终得到的结果是:

4ae8f407a77288046be1be87d905ec08.png

与我们示意图中的执行过程相同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值