数据结构--二叉树的基本操作

二叉树概念

概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看 起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

下面是一些简单的概念。

结点的度:一个结点含有子树的个数称为该结点的度; 

树的度:一棵树中,所有结点度的最大值称为树的度;

叶子结点或终端结点度为0的结点称为叶结点;

双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点;

孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点; 

根结点:一棵树中,没有双亲结点的结点;

结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推

树的高度或深度:树中结点的最大层次; 

非终端结点或分支结点:度不为0的结点;

兄弟结点:具有相同父结点的结点互称为兄弟结点;

堂兄弟结点:双亲在同一层的结点互为堂兄弟;

结点的祖先:从根到该结点所经分支上的所有结点;

子孙:以某结点为根的子树中任一结点都称为该结点的子孙。

森林:由m(m>=0)棵互不相交的树组成的集合称为森林 。

特点

1.根节点没有前驱节点,可以通过根节点来遍历这棵树。

2.除根结点外,其余结点被分成M(M > 0)个互不相交的集合T1、T2、......、Tm,其中每一个集合Ti (1 <= i <= m) 又是一棵与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。这是什么意思呢?其实就是一棵树可以分为多个子树,根节点以外的节点又可以分别看成一棵树。

3.树是递归定义的。这句话指的是树这种数据结构可以通过递归的方式来定义和构建。

代码实现

1.定义一个二叉树的类

一个二叉树,每个节点包含有自己的值,指向左右孩子,由此来定义一个树类。

public class BinaryTree {
    //定义树的节点
    public class TreeNode{
        //节点带的值
        public char val;
        //左孩子
        public TreeNode left;
        //右孩子
        public TreeNode right;
        //实例化时只需要传递值,因为不知道节点左右孩子的地址
        public TreeNode(char val) {
            this.val = val;
        }
    }

2.创建一个简单的二叉树

这里使用穷举的方式创建了一颗二叉树,后面会讲到使用更简单的方式创建二叉树。

将头节点A作为根节点返回。

 public TreeNode createTree() {
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');
        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        C.left = F;
        C.right = G;
        E.right = H;
        return A;
    }

这棵二叉树的样子为:

3.二叉树的前序遍历,中序遍历,后序遍历

三种遍历的思想

前序遍历(Preorder Traversal): 在前序遍历中,首先访问根节点,然后按照左孩子、右孩子的顺序递归遍历子树。可以用以下递归方式进行前序遍历:先访问根节点,然后递归前序遍历左子树,最后递归前序遍历右子树。

递归遍历上图中的树,首先从根节点A出发(打印节点值),遍历A的左子树,最后遍历右子树C。

这里我用图来描述一下前序遍历的过程,中序遍历和后序遍历与前序遍历相似,不过多画图了。

中序遍历(Inorder Traversal): 在中序遍历中,先递归中序遍历左子树,然后访问根节点,最后递归中序遍历右子树。中序遍历的顺序是左子树 -> 根节点 -> 右子树。

递归遍历上图中的树,首先遍历A的左子树,打印节点值 ,最后遍历右子树C。

后序遍历(Postorder Traversal): 在后序遍历中,先递归后序遍历左子树,然后递归后序遍历右子树,最后访问根节点。后序遍历的顺序是左子树 -> 右子树 -> 根节点。

递归遍历上图中的树,首先遍历A的左子树,遍历右子树C ,最后打印节点值。

实现(递归实现)

在进行遍历之前,首先判断节点是否是空节点,如果为空,直接返回,这也是递归的结束条件,当向下递归时遇到的节点为空,则直接return返回了,递归结束,返回上个函数中。

1.前序遍历

 public void preOrder(TreeNode root) {
        //节点为空直接返回
        if(root == null) {
            return;
        }
        //打印根节点
        System.out.print(root.val+" ");
        //遍历左子树
        preOrder(root.left);
        //遍历右子树
        preOrder(root.right);
    }

2.中序遍历

 public void inOrder(TreeNode root) {
        //节点为空直接返回
        if(root == null) {
            return;
        }
        //先遍历左子树
        inOrder(root.left);
        //打印节点值
        System.out.print(root.val+" ");
        //遍历右子树
        inOrder(root.right);
    }

3.后序遍历

 public void lastOrder(TreeNode root) {
        //节点为空直接返回
        if (root == null) {
            return;
        }
        //遍历左子树
        lastOrder(root.left);
        //遍历右子树
        lastOrder(root.right);
        //打印节点值
        System.out.print(root.val+" ");
    }

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值