你好!二叉树【JAVA】

1.二叉树

节点组成,并且每个节点最多有两个子节点,分别称为左子节点右子节点,不存在子节点的节点称为叶子节点。二叉树常见的遍历方式有前序遍历**、中序遍历以及后序遍历前序遍历先遍历根节点然后遍历左子树和右子树中序遍历先遍历左子树,然后遍历根节点和右子树后序遍历先遍历左子树和右子树,最后遍历根节点****。**

2.满|完全二叉树

如果该二叉树的所有叶子节点都在最后一层,并且结点总数=2^n-1,n 为层数,则我们称为满二叉树。
如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,我们称为完全二叉树

3.二叉树遍历

三种方式:

  • 1.前序遍历
  • 2.中序遍历
  • 3.后序遍历

注:根据根节点的输出顺序,判断是前中后遍历~

3.1.前序遍历

前序遍历:先访问根节点**,再访问左子树,**最后访问右子树

1.思路分析

  • 1.先输出当前节点(根节点)
  • 2.若左子节点不为空,则递归继续遍历
  • 3.若右子节点不为空,则递归继续遍历

2.代码实战

java 复制代码
    /**
     * 前序遍历
     */
    public void preOrder() {
        System.out.println(this);//先输出根节点
        //向左子节点递归
        if (this.left != null) {
            this.left.preOrder();
        }
        //向右子节点递归
        if (this.right != null) {
            this.right.preOrder();
        }

3.2.中序遍历

中序遍历:先遍历左子树再输出根节点**,**再遍历右子树

1.思路分析

1.若当前节点的左子节点不为空,则递归遍历

2.输出当前节点(根节点)

3.若当前节点的左子节点不为空,则递归遍历

2.代码实战

java 复制代码
    /**
     * 中序遍历
     */
    public void infixOrder() {
        //先递归左子节点遍历
        if (this.left != null) {
            this.left.infixOrder();
        }
        //输出当前节点
        System.out.println(this);
        //递归右子节点遍历
        if (this.right != null) {
            this.right.infixOrder();
        }

3.3.后序遍历

后序遍历:先遍历左子树,再遍历右子树,最后输出根节点

1.思路分析

1.若当前节点的左子节点不为空,则递归遍历

2.若当前节点的右子节点不为空,则递归遍历

3.输出当前节点(根节点)

2.代码实战

java 复制代码
/**
     * 后序遍历
     */
    public void postOrder() {
        if (this.left != null) {
            this.left.postOrder();
        }
        if (this.right != null) {
            this.right.postOrder();
        }
        System.out.println(this);
    }

3.4创建二叉树遍历

java 复制代码
/**
 * 定义一个二叉树
 */
class Tree {
    private HeroNode 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("当前二叉树为空无法遍历");
        }
    }
}

4.查找指定节点

三种方式:

  • 1.前序查找
  • 2.中序查找
  • 3.后序查找

注:后序查找相对比较快一点~

4.1.前序查找

1.思路分析

  • 1.判断当前节点是否是要查找的
  • 2.若相等,则返回
  • 3.若不相等,则判断当前节点的左子节点是否为空,不为空,向左递归查找
  • 4.若左递归找到,则返回。否则继续判断当前节点的右子节点是否为空,若不为空,则向右递归

2.代码实现

java 复制代码
    /**
     * 前序查找
     */
    public HeroNode preOrderSearch(int no) {
        //判断当前节点是否相等
        if (this.no == no) {
            return this;
        }
        //定义变量,接收递归返回值
        HeroNode tempNode = null;
        //判断左子节点是否为空,向左子节点递归
        if (this.left != null) {
            tempNode = this.left.preOrderSearch(no);
        }
        //说明左递归找到
        if (tempNode != null) {
            return tempNode;
        }
        //左递归未找到,判断右子节点是否为空,并向右递归
        if (this.right != null) {
            tempNode = this.right.preOrderSearch(no);
        }
        return tempNode;
    }

4.2.中序查找

1.思路分析

1.判断当前节点的左子节点是否为空,若不为空,则向左递归

2.如果找到,则返回;

3.如果没有找到,则和当前节点比较,如果相等,则返回当前接节点,否则继续右递归

4.如果右递归找到,则返回,否则返回null

2.代码实现

java 复制代码
    /**
     * 中序查找
     */
    public HeroNode infixOrderSearch(int no) {
        HeroNode tempNode = null;
        //判断当前节点的左子节点是否为空,并递归
        if (this.left != null) {
            tempNode = this.left.infixOrderSearch(no);
        }
        //判断是否找到
        if (tempNode != null) {
            return tempNode;
        }
        //未找到,判断当前节点是否相等
        if (this.no==no){
            return this;
        }
        //不等,判断右子节点是否为空,向有递归
        if (this.right!=null){
            tempNode=this.right.infixOrderSearch(no);
        }
        return tempNode;
    }

4.3.后序查找

1.思路分析

1.判断当前节点的左子节点是否为空,如果不为空,则左递归查找

2.如果找到,则返回,如果没有找到,判断当前接待的右子节点是否为空,如果不为空,则有递归查找,如果找到,则返回

3.如果有递归没有找到,就和当前节点比较,找到则返回,否则返回null

2.代码实现

java 复制代码
    /**
     * 后序查找
     */
    public HeroNode postOrderSearch(int no){
        HeroNode tempNode=null;
        //判断当前节点的左子节点
        if (this.left!=null){
            tempNode=this.left.postOrderSearch(no);
        }
        //判断是否找到
        if (tempNode!=null){
            return tempNode;
        }
        //未找到,判断右子节点是否为空,并递归
        if (this.right!=null){
            tempNode=this.right.postOrderSearch(no);
        }
        //判断有递归是否找到
        if (tempNode!=null){
            return tempNode;
        }
        //左右均未找到,比较当前节点
        if (this.no==no){
            return this;
        }
        return tempNode;
    }

4.4创建二叉树查找

java 复制代码
/**
 * 定义一个二叉树
 */
class Tree {
    private HeroNode root;

    public void setRoot(HeroNode root) {
        this.root = root;
    }

    //前序查找
    public HeroNode preOrderSearch(int no) {
        if (this.root != null) {
            return this.root.preOrderSearch(no);
        } else {
            return null;
        }
    }

    //中序查找
    public HeroNode infixOrderSearch(int no) {
        if (this.root != null) {
            return this.root.infixOrderSearch(no);
        } else {
            return null;
        }
    }

    //后序查找
    public HeroNode postOrderSearch(int no) {
        if (this.root != null) {
            return this.root.postOrderSearch(no);
        } else {
            return null;
        }
    }
}

5.删除节点

  • 如果删除的节点是叶子节点,则删除该节点
  • 如果删除的节点是非叶子节点,则删除该子树

5.1思路分析

  • 1.当前二叉树是单向的,判断当前节点的子节点是否是要删除的节点,而不能判断,当前节点是不是要删除的
  • 2.如果当前节点的左子节点不为空,并且左子节点就是我们要删除的,就将this.left=null,并返回,结束;否则看右子节点
  • 3.如果当前节点的右子节点不为空,并且右子节点就是要删除的节点,就将this.rigth=null,并返回,结束;
  • 4.如果第二步,第三步递归都没有删除,则需要向左子树递归删除,如果左递归没有删除,则向右子树递归删除

5.2代码实现

java 复制代码
    /**
     * 递归删除节点
     */
    public void deleteNode(int no) {
        //当前节点的左子节点不为空,并且是要删除的节点,则置为空
        if (this.left != null && this.left.no == no) {
            this.left = null;
            return;
        }
        //当前节点的右子节点不为空,并且是要删除的节点,则置为空
        if (this.right != null && this.right.no == no) {
            this.right = null;
            return;
        }
        //向左子树递归
        if (this.left != null) {
            this.left.deleteNode(no);
        }
        //向右子树递归
        if (this.right != null) {
            this.right.deleteNode(no);
        }
    }

5.3创建二叉树删除

java 复制代码
/**
 * 定义一个二叉树
 */
class Tree {
    private HeroNode root;

    public void setRoot(HeroNode root) {
        this.root = root;
    }

    //删除指定节点
    public void deleteNode(int no) {
        if (this.root != null) {
            //如果只有一个root节点,判断root是否是要删除的
            if (root.getNo() == no) {
                root = null;
                return;
            }else {
                root.deleteNode(no);
            }
        } else {
            System.out.println("空树无法删除");
        }
    }
}

6.顺序存储二叉树

顺序存储二叉树,也称为顺序存储结构,是一种二叉树的存储方法。在顺序存储结构中,将二叉树的节点按照层次顺序存储在一个数组中,使得二叉树的节点可以用数组元素来表示。通常采用广义表的形式将整棵树存储在一个一维数组中,而且该数组满足完全二叉树的特性。

1.数组方式存放arr=【1,2,3,4,5,6,7】

2.依然可以使用前序、中序、后序遍历

6.1顺序存储二叉树的特点

  • 顺序二叉树通常只考虑完全二叉树
  • 第n个元素的左子节点为2*n+1
  • 第n个元素的右子节点为2*n+2
  • 第n个元素的父节点为(n-1)/2

注:n表示二叉树中的第几个元素(下标从0开始)

6.2代码实现

java 复制代码
/**
 * 创建二叉树,实现顺序存储
 */
class ArrTree {
    private int[] arr;

    public ArrTree(int[] arr) {
        this.arr = arr;
    }

    //前序存储二叉树
    public void preOrder(int index) {
        //如果数组为空 或者 arr.length==0
        if (arr == null || arr.length == 0) {
            System.out.println("数组为空,无法使用前序遍历");
        }
        System.out.println(arr[index]);
        //向左递归
        if ((index * 2 + 1) < arr.length) {
            preOrder(index * 2 + 1);
        }
        //向右递归
        if ((index * 2 + 2) < arr.length) {
            preOrder(index * 2 + 2);
        }
    }

    //中序存储二叉树
    public void infixOrder(int index) {
        if (arr == null || arr.length == 0) {
            System.out.println();
        }
        if ((index * 2 + 1) < arr.length) {
            infixOrder(index * 2 + 1);
        }
        System.out.println(arr[index]);
        //向右递归
        if ((index * 2 + 2) < arr.length) {
            preOrder(index * 2 + 2);
        }
    }

    //后序存储二叉树
    public void postOrder(int index) {
        if (arr == null || arr.length == 0) {
            System.out.println();
        }
        if ((index * 2 + 1) < arr.length) {
            infixOrder(index * 2 + 1);
        }
        //向右递归
        if ((index * 2 + 2) < arr.length) {
            preOrder(index * 2 + 2);
        }
        System.out.println(arr[index]);
    }
}

相关推荐
浮生如梦_1 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck2 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei2 小时前
java的类加载机制的学习
java·学习
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
码农小旋风3 小时前
详解K8S--声明式API
后端
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml44 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍