数据结构与算法-二叉树

这篇具有很好参考价值的文章主要介绍了数据结构与算法-二叉树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

        在计算机科学中,数据结构是组织和存储数据的基础框架,而算法则是处理这些数据的核心逻辑。在这众多的数据结构中,二叉树因其独特的层级结构、高效的搜索和插入操作,成为广泛应用的一种非线性数据结构。本文将深入探讨二叉树的定义、种类、操作方法以及实际应用场景。

一、什么是二叉树?

        二叉树(Binary Tree) 是一种每个节点最多有两个子节点的树形数据结构。它具有根节点、叶子节点和内部节点的概念,其中:

  • 根节点是没有父节点的节点。
  • 叶子节点是没有任何子节点的节点。
  • 内部节点既有左子节点也有右子节点。

二、二叉树的种类及特点

  1. 二叉查找树(Binary Search Tree, BST):每个节点的左子树中的所有节点的值都小于该节点,而其右子树中所有节点的值都大于该节点。这种特性使得BST在进行查找、插入和删除操作时,时间复杂度可达到O(log n)。

  2. 完全二叉树(Complete Binary Tree):除了最后一层外,每一层的节点数都达到最大,并且最后一层的节点都尽可能地集中在左边。

  3. 满二叉树(Full Binary Tree):所有层的节点数都达到最大,即除了叶子节点外,每个节点都有两个子节点。

  4. 平衡二叉树(Balanced Binary Tree):左右两个子树的高度差不超过1,如AVL树和红黑树。这类二叉树保证了查找等操作的时间复杂度始终为O(log n),极大地提高了效率。

三、二叉树的基本操作

  1. 创建二叉树:从根节点开始,递归地或迭代地添加节点至合适的位置。

  2. 遍历二叉树:常见的遍历方式有前序遍历(根-左-右)、中序遍历(左-根-右)、后序遍历(左-右-根)和层次遍历(按层次从上到下、从左到右)。

  3. 查找节点:根据二叉查找树的性质,在BST中可以通过比较目标值与当前节点值来确定向左还是向右子树继续查找。

  4. 插入节点:在合适的子树位置创建新节点,保持BST的性质不变。

  5. 删除节点:针对不同情况(无子节点、仅有一个子节点或有两个子节点),采用不同的策略移除节点并调整树结构。

四、二叉树的实际应用

二叉树广泛应用于软件开发和计算机科学领域,包括但不限于:

  • 数据库索引:B树和B+树作为特殊的平衡二叉树,常用于数据库系统建立索引以提高查询速度。

  • 文件系统:NTFS等现代文件系统使用类似于B+树的结构管理目录和文件。

  • 编译器:词法分析阶段利用二叉树实现符号表;语法分析阶段构建抽象语法树(AST)。

  • 图形学:场景图、渲染队列等常常采用树状结构表示。

  • 动态规划问题:一些动态规划问题可以借助二叉树来优化求解过程,例如斐波那契数列可以用记忆化搜索结合二叉树进行高效计算。

五、二叉树的代码实践

1.节点类

class HeroNode {
    private int no;
    private String name;
    private HeroNode lift;
    private HeroNode right;


    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 getLift() {
        return lift;
    }

    public void setLift(HeroNode lift) {
        this.lift = lift;
    }

    public HeroNode getRight() {
        return right;
    }

    public void setRight(HeroNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

2.前序遍历 

    //    编写前序遍历方法
//    思路
//    1.前序的顺序是 根左右
//    2.先输出根节点
//    3.左节点不为空递归向左子树前序遍历
//    4.右节点不为空递归向右子树前序遍历
    public void preOrder() {
        System.out.println(this);
        if (this.lift != null) {
            this.lift.preOrder();
        }
        if (this.right != null) {
            this.right.preOrder();
        }
    }

3.中序遍历 

    //    中序遍历
//    思路
//    1.中序的顺序是 左根右
//    2.左节点不为空递归中序遍历
//    3.输出当前节点
//    4.右节点不为空递归向右子树中序遍历
    public void infixOrder() {
        if (this.lift != null) {
            this.lift.infixOrder();
        }
        System.out.println(this);
        if (this.right != null) {
            this.right.infixOrder();
        }
    }

4.后序遍历 

    //    后序遍历
//    思路
//    1. 后序的顺序是 左右跟
//    2.左节点不为空递归后序遍历
//    3.右节点不为空递归向右子树后序遍历
//    4.输出当前节点
    public void postOrder() {
        if (this.lift != null) {
            lift.postOrder();
        }
        if (this.right != null) {
            this.right.postOrder();
        }
        System.out.println(this);
    }

5.先序遍历查找 

    //    前序遍历查找
//    思路
//    1.先比较当前节点的编号是否和查找值编号相同,相同直接返回当前节点,不相同向左递归查找
//    2.左子节点不为空,向左递归查找,若找到则返回当前节点否则向右递归查找
//    3.右子节点不为空,向右递归查找,若找到则返回当前节点否则返回空
    public HeroNode preOrderSearch(int heroNo) {
        if (this.no == heroNo) {
            return this;
        }
        HeroNode heroNode = null;
        if (this.lift != null) {
            heroNode = this.lift.preOrderSearch(heroNo);
        }
        if (heroNode != null) {
            return heroNode;
        }
        if (this.right != null) {
            heroNode = this.right.preOrderSearch(heroNo);
        }
        return heroNode;
    }

6.中序遍历查找

    //    中序遍历查找
//    思路
//    1.左子节点不为空,向左递归查找,若找到则返回当前节点否则比较当前节点
//    2.比较当前节点的编号是否和查找值编号相同,相同直接返回当前节点,不相同向右递归查找
//    3.右子节点不为空,向右递归查找,若找到则返回当前节点否则返回空
    public HeroNode infixOrderSearch(int heroNo) {
        HeroNode heroNode = null;
        if (this.lift != null) {
            heroNode = this.lift.infixOrderSearch(heroNo);
        }
        if (heroNode != null) {
            return heroNode;
        }
        if (this.no == heroNo) {
            return this;
        }
        if (this.right != null) {
            heroNode = this.right.infixOrderSearch(heroNo);
        }
        return heroNode;
    }

7.后序遍历查找

    //    后序遍历查找
//    思路
//    1.左子节点不为空,向左递归查找,若找到则返回当前节点否则向右递归查找
//    2.右子节点不为空,向右递归查找,若找到则返回当前节点否则比较当前节点
//    3.比较当前节点的编号是否和查找值编号相同,相同直接返回当前节点,不相同返回null
    public HeroNode postOrderSearch(int heroNo) {
        HeroNode heroNode = null;
        if (this.lift != null) {
            heroNode = this.lift.postOrderSearch(heroNo);
        }
        if (heroNode != null) {
            return heroNode;
        }
        if (this.right != null) {
            heroNode = this.right.postOrderSearch(heroNo);
        }
        if (heroNode != null) {
            return heroNode;
        }
        if (this.no == heroNo) {
            return this;
        }
        return heroNode;
    }

8.二叉树类遍历查找方法 

//二叉树类
class BinaryTree {
    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("该二叉树为空!!!");
        }
    }


    //    先序遍历
    public HeroNode preOrderSearch(int heroNo) {
        if (this.root != null) {
            return this.root.preOrderSearch(heroNo);
        } else {
            return null;
        }
    }

    //    中序遍历
    public HeroNode infixOrderSearch(int heroNo) {
        if (this.root != null) {
            return this.root.infixOrderSearch(heroNo);
        } else {
            return null;
        }
    }

    //    后序遍历
    public HeroNode postOrderSearch(int heroNo) {
        if (this.root != null) {
            return this.root.postOrderSearch(heroNo);
        } else {
            return null;
        }
    }
}

 

六、总结

        二叉树作为基础而又灵活的数据结构,其多样化的形态和丰富的操作方法使其在实际工程应用中占据重要地位。掌握二叉树的原理和实现不仅可以提升编程能力,而且有助于理解更复杂的算法设计和数据结构优化。在不断探索和实践中,我们能够更加深刻地领略到数据结构与算法的魅力,并在实际项目中发挥关键作用。文章来源地址https://www.toymoban.com/news/detail-838004.html

到了这里,关于数据结构与算法-二叉树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构与算法之《二叉树》详解

    文章目录 一、树的概念及结构 二、二叉树的概念及结构 2、1 二叉树的概念 2、2 二叉树的特点 2、3 二叉树的结构(图片) 2、4 特殊的二叉树 三、二叉树的代码及思路实现 3、1 二叉树的存储结构 3、1、1 二叉树的顺序存储结构 3、1、2 二叉树的链式存储结构 3、2 二叉树链式

    2024年02月01日
    浏览(45)
  • 数据结构与算法——树与二叉树

    😊各位小伙伴久等了,本专栏新文章出炉了!!! 我又回来啦,接下来的时间里,我会持续把数据结构与算法专栏更新完。 👉树型结构👈 是一类重要的 ✍非线性数据结构 ,其中以树和二叉树最为常用,直观来看,树是以分支关系定义的层次结构。树型结构在客观世界中

    2024年02月11日
    浏览(45)
  • 【数据结构与算法】树与二叉树

    除了之前我们讲的栈、队列、链表等线性结构,数据结构中还有着一对多的 非线性结构 ——— 树 。 树是有 n 个结点组成的有限集,当n=0时为空树,在任意一颗非空树中,有且仅有一个 特定的根结点 ;当n1时,其余结点又可以分为一棵树,称为根的 子树 。 如下图所示: A为

    2023年04月09日
    浏览(49)
  • 【数据结构和算法】---二叉树(1)--树概念及结构

    树是一种 非线性的数据结构 ,它是由n(n=0)个有限结点组成一个具有层次关系的集合。之所以叫它树,是因为将此结构倒转后与现实生活中的树极其相似,一个主干分出多个分支,分支还可继续分展。 有一个特殊的结点,称为 根结点 ,根节点没有前驱结点; 除根节点外,

    2024年02月03日
    浏览(43)
  • 【数据结构】二叉树算法讲解(定义+算法原理+源码)

    博主介绍:✌全网粉丝喜爱+、前后端领域优质创作者、本质互联网精神、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战✌有需要可以联系作者我哦! 🍅附上相关C语言版源码讲解🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找

    2024年01月23日
    浏览(54)
  • 【数据结构与算法】力扣:对称二叉树

    给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root = [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root = [1,2,2,null,3,null,3] 输出:false 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/symmetric-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请

    2024年02月13日
    浏览(37)
  • 《数据结构与算法》之二叉树(补充树)

    二叉搜索树,也称二叉排序树或二叉查找树 二叉搜索树:一棵二叉树,可以为空,如果不为空,应该满足以下性质: 非空左子树的所有结点小于其根结点的键值 非空右子树的所有结点大于其根结点的键值 左右子树都是二叉搜索树 对于二叉树的查找,其实沿用的是分治法的

    2024年02月08日
    浏览(48)
  • 数据结构与算法-二叉树的遍历

    🌞 “少年没有乌托邦,心向远方自明朗!” 二叉树的遍历是按照一定次序访问二叉树中的所有结点,且每个结点仅被访问一次的过程。遍历线性结构是容易解决的,而二叉树的结构是非线性结构,需要寻找规律,使二叉树的结点排列在一个线性队列上,便于遍历。 由二叉树

    2024年02月08日
    浏览(46)
  • 算法与数据结构(五)--二叉树入门

    符号表的增删查操作,随着元素个数N的增多,其耗时也是线性增多的,时间复杂度都是O(n),为了提高运算效率,我们学习树这种数据结构。 目录 一.树的基本定义 二.树的相关术语 三.二叉树的基本定义 四.二叉树的链表实现 1.二叉树结点类 结点类API设计:​编辑 代码实现:

    2024年02月12日
    浏览(46)
  • 【Java 数据结构】二叉树

    树是一种 非线性 的数据结构,它是由n(n=0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 。 有一个特殊的结点,称为根结点,根结点没有前驱结点 除根结点外,其余结点被分成M(M 0)个互不相交的

    2024年02月20日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包