【❤️算法系列之二叉树的实现(包含前序、中序、后序遍历以及节点的查找和删除)❤️】


💌1.何谓树

在这里插入图片描述

💙 1.1.树的定义

树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。

💙 1.2.树的特点

(1)每个节点有零个或多个子节点;
(2) 没有父节点的节点称为根节点;
(3) 每一个非根节点有且只有一个父节点;
(4) 除了根节点外,每个子节点可以分为多个不相交的子树。

💙 1.3.树的基本术语

结点的度:结点拥有的子树的数目。
叶子节点:度为零的结点。
树的度:树中结点的最大的度。
树的层次:根结点的层次为1,其余结点的层次等于该结点的双亲结点的层次加1。
树的高度:树中结点的最大层次。
无序树:如果树中结点的各子树之间的次序是不重要的,可以交换位置。
有序树:如果树中结点的各子树之间的次序是重要的, 不可以交换位置。



💌2.认识二叉树

🔥 1.1.二叉树的定义

二叉树是每个节点最多有两个子树的树结构。它有五种基本形态:二叉树可以是空集;根可以有空的左子树或右子树;或者左、右子树皆为空。

在这里插入图片描述

🔥 1.2.二叉树的分类

💦 1.2.1.满二叉树

除了叶子节点之外,其他所有的节点都必须包含左子节点和右子节点
在这里插入图片描述

💦 1.2.2.完全二叉树

对于n层的二叉树,它的n-1层的节点个数必须达到最大值。第n层包含叶子节点,并且叶子节点从左到右依次排列

在这里插入图片描述

💦 1.2.3.平衡二叉树

它的任意节点的左右子树的高度差的绝对值不超过1
在这里插入图片描述


💌3.二叉树的遍历

🔥 3.1.前序遍历

在这里插入图片描述

请添加图片描述

//前序遍历  根->左—>右
    public void preOrder(TreeNode temp) {
        if (temp == null) {  //递归结束条件
            return;
        }
        System.out.println(temp);
        preOrder(temp.getLeft());
        preOrder(temp.getRight());
    }

🔥 3.2.中序遍历

在这里插入图片描述

//中序遍历  左->根->右
    public void infixOrder(TreeNode temp) {
        if (temp == null) {
            return;
        }
        preOrder(temp.getLeft());
        System.out.println(temp);
        preOrder(temp.getRight());
    }

🔥 3.3.后序遍历

在这里插入图片描述
请添加图片描述

    //后序遍历   左->右->根
    public void sufOrder(TreeNode temp) {
        if (temp == null) {
            return;
        }
        preOrder(temp.getLeft());
        preOrder(temp.getRight());
        System.out.println(temp);
    }


💌4.二叉树节点的查找

以前序遍历为例
一直递归下去,如果找到了进行返回即可。然后用resultNode进行接收,直接返回

🔥 4.1.前序查找

    /**
     * 前序查找
     * @param temp 节点
     * @param no 带查询id
     * @return 查询到的
     */
    public TreeNode preSearch(TreeNode temp, int no) {

        if (temp == null) {
            return null;
        }
        if (temp.id == no) { //说明找到了,直接返回
            return temp;
        }
        TreeNode resultNode = null;
        if (temp.getLeft() != null) {
            resultNode = preSearch(temp.getLeft(), no);
        }
        if (resultNode != null) {
            return  resultNode; //如果找到,直接返回,就不用再执行下面的right
        }
        if (temp.getRight() != null) {
            resultNode = preSearch(temp.getRight(), no);
        }
        return resultNode;
    }

🔥 4.2.中序查找

    /**
     * 中序查找
     * @param cur 节点
     * @param no 带查询id
     * @return 查询到的
     */
    public TreeNode infixSearch(TreeNode cur, int no) {
        if (cur == null) {
            return null;
        }
        TreeNode resultNode = null;
        if (cur.getLeft() != null) {
            resultNode = infixSearch(cur.getLeft(), no);
        }
        if (resultNode != null) {
            return resultNode;
        }
        if (cur.id == no) {
            return cur;
        }
        if (cur.getRight() != null) {
            resultNode = infixSearch(cur.getRight(), no);
        }
        return resultNode;
    }

🔥 4.3.后序查找

/**
     * 后序查找
     * @param last 节点
     * @param no 带查询id
     * @return 查询到的
     */
    public TreeNode sufSearch(TreeNode last, int no) {
        if (last == null) {
            return null;
        }
        TreeNode resultNode = null;
        if (last.getLeft() != null) {
            resultNode = sufSearch(last.getRight(), no);
        }
        if (resultNode != null) {
            return resultNode;
        }
        if (last.getRight() != null) {
            resultNode = sufSearch(last.getRight(), no);
        }
        if (last.id == no) {
            resultNode = last;
        }
        return resultNode;
    }

💌5.二叉树节点的删除

💥删除时如果不是叶子节点需要将整个子树一块删除

这里需要注解的是结束条件,有两种情况(以左为例子)

1.一直往下递归,没有找到该节点,直接返回即可
2.head.getLeft().id == no,说明它的左子节点是需要进行删除

    /**
     * 如果是叶子节点,则将叶子节点删除即可
     * 如果不是叶子节点,则需要将相关的子树都删除
     * @param no id
     */
    public void deleteTreeNode(TreeNode head, int no) {
        if (head.getLeft() == null || head.getLeft().id == no) {
            head.setLeft(null);
            return;
        } else if (head.getRight() == null || head.getRight().id == no) {
            head.setRight(null);
            return;
        }
        deleteTreeNode(head.getLeft(), no);
        deleteTreeNode(head.getRight(), no);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thecoastlines

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值