数据结构——树

1. 为什么需要树这种数据结构?
  1. 数组存储方式的优缺点:

    • 优点:可以直接通过下标访问元素,速度快。当是有序数组的时候,还可以使用二分查找提高查询的速度。即读取效率较高。

    • 缺点:如果需要检索某个具体的值,或插入值的时候,数组会整体移动,这时候效率就较低。即存储效率较低

  2. 链式存储方式的优缺点:

    • 优点:存储效率较高。例如在插入一个数值节点,只需要将插入节点链接到链表中就可以了,删除效率也较高。

    • 缺点:检索效率较低,例如当需要检索某个值的时候,需要从头节点开始遍历。即读取效率较低

  3. 树存储方式

    能够同时提高数据的存储和读取效率。例如二叉排序树,既可以保证数据的检索速度,同时可以保证数据的插入、删除、修改的速度。

2. 树的示意图和常用术语

2.1 树的示意图如下:

在这里插入图片描述
2.2 常用术语

  • 节点。就是图中的ABCDEFGH对象

  • 根节点

  • 父节点

  • 子节点

  • 叶子节点(没有子节点的节点)

  • 节点的权(节点的值)

  • 路径(从root节点找到该节点的路线)

  • 层(就是图中标注的1、2、3、4层)

  • 树的高度(最大层数)

  • 森林(多颗子树构成一个森林)

3. 二叉树
  1. 树的每个节点最多只能有两个子节点的树叫作二叉树。二叉树的子节点分为左节点和右节点。

  2. 如果二叉树的所有叶子节点都在最后一层,并且节点总数等于2^n - 1,其中n为层数,那么就称该树为满二叉树

在这里插入图片描述

  1. 如果二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,那么就称该树为完全二叉树。

在这里插入图片描述

4. 二叉树的遍历
  1. 前序遍历: 先输出父节点,再遍历左子树,最后遍历右子树

  2. 中序遍历: 先遍历左子树,再输出父节点,最后遍历右子树

  3. 后续遍历: 先遍历左子树,再遍历右子树,最后输出父节点

总结:看输出父节点的顺序,就确定是前序、中序还是后序。

5. 二叉树前序、中序、后序遍历的步骤
  1. 创建一颗二叉树

  2. 前序遍历

    • 先输出当前节点(初始的时候是root节点)

    • 如果左子节点不为空,则递归继续前序遍历

    • 如果右子节点不为空,则递归继续前序遍历

  3. 中序遍历

    • 如果当前节点的左子节点不为空,则递归中序遍历

    • 输出当前节点

    • 如果当前节点的右子节点不为空,则递归中序遍历

  4. 后序遍历

    • 如果当前节点的左子节点不为空,则递归后序遍历

    • 如果当前节点的右子节点不为空,则递归后序遍历

    • 输出当前节点

6. 二叉树前序、中序、后序遍历的代码实现
  1. 创建一个节点,并在节点中实现前序、中序、后序遍历

     //创建一个HeroNode节点
     class HeroNode {
         private int no;
         private String name;
         private HeroNode left;
         private HeroNode right;
     
         public HeroNode(int no, String name) {
             this.no = no;
             this.name = name;
         }
     
         public int getNo() {
             return no;
         }
     
         public String getName() {
             return name;
         }
     
         public HeroNode getLeft() {
             return left;
         }
     
         public HeroNode getRight() {
             return right;
         }
     
         public void setNo(int no) {
             this.no = no;
         }
     
         public void setName(String name) {
             this.name = name;
         }
     
         public void setLeft(HeroNode left) {
             this.left = left;
         }
     
         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.left != nul
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值