【数据结构与算法】第十一章:二叉树深入浅出

简介: 在二叉树的一些应用中,常常要求在数中查找具有某种特征的结点,或者是对树中的全部结点逐一进行处理,这就提出了一个遍历二叉树的问题。本章将详细介绍二叉树的存储和遍历。

🙊🙊作者主页:🔗求不脱发的博客

📔📔 精选专栏:🔗数据结构与算法

📋📋 精彩摘要:在二叉树的一些应用中,常常要求在数中查找具有某种特征的结点,或者是对树中的全部结点逐一进行处理,这就提出了一个遍历二叉树的问题。本章将详细介绍二叉树的存储和遍历。

💞💞觉得文章还不错的话欢迎大家点赞👍➕收藏⭐️➕评论💬支持博主🤞


📚目录

📖【数据结构与算法】第十一章:二叉树深入浅出

📝1️⃣二叉树的存储

📝2️⃣二叉树的遍历


📖【数据结构与算法】第十一章:二叉树深入浅出


📝1️⃣二叉树的存储

✨二叉树的顺序存储

【实现】

对于二叉树的顺序存储,需要按满二叉树的结点层次编号,依次存放二叉树中的数据元素。

image.gif编辑

【特点】

    • 结点间关系蕴含在其存储位置中。
    • 浪费空间,适合存满二叉树或完全二叉树。

    ✨二叉树的链式存储

    对于二叉树的链式存储,需借助左右指针用来存放结点间的关系位置。

    image.gif编辑

    【结构定义】

    typedef struct BiNode
    {
        TElemType data;//存放数据
        struct BiNode *lchild,*rchild;//左右孩子指针
    }BiNode,*BiTree;

    image.gif

    【练习】

    在n个结点的二叉链表中,有 ———个空指针域。

    【分析】

    n个结点的二叉链表必有2n个指针域。除根结点外,每个结点有且仅有一个双亲,所以只会有,-1个结点的链域存放指针,指向非空子女结点。

    即 :空指针域 = 2n - (n-1)

    ✨三叉链表

    三叉链表类似二叉链表,不同的是三叉链表多出一个parent指针,用来存储上一个结点即父结点的地址。

    【结构定义】

    typedef struct TriTNode
    {
        TelemType data;
        struct TriTNode *lchild,*rchild,*parent;
    }TriTNode,*TriTree;

    image.gif

    例如:

    image.gif编辑

    📝2️⃣二叉树的遍历

    ✨遍历

    【定义】:指按照某条搜索路线遍历每个接地那且不重复(又称为周游)

    【用途】:它是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的基础和核心。

    【规则】:先序遍历、中序遍历、后序遍历。

    image.gif编辑

    例如,对于上图中的树

      • 先序遍历:ABEKLFDHMJ
      • 中序遍历:KELBFAHMDJ
      • 后续遍历:KLEFBMHJDA

      ✨先序遍历

      【分析】

        1. 若果二叉树为空,则空操作。
        2. 否则:
          1. 先访问根结点,
          2. 先序遍历左子树,
          3. 先序遍历右子树。

            【实现】

            Status PreOrderTraverse(BiTree T)
            {
                if(T==NULL)
                    return OK;
                else
                {
                    cout<<T->data;//访问根结点
                    PreOrderTraverse(T->lchild);//递归遍历左子树
                    PreOrderTraverse(T->rchild);//递归遍历右子树
                }
            }

            image.gif

            ✨先序遍历

            【分析】

              1. 若果二叉树为空,则空操作。
              2. 否则:
                1. 中序遍历左子树
                2. 访问根节点
                3. 中序遍历右子树

                  【实现】

                  Status InOrderTraverse(BiTree T)
                  {
                      if(T==NULL)
                          return OK;
                      else
                      {
                          InOrderTraverse(T->lchild);//递归遍历左子树
                          cout<<T->data;//访问根结点
                          InOrderTraverse(T->rchild);//递归遍历右子树
                      }
                  }

                  image.gif

                  ✨后序遍历

                  【分析】

                    1. 若果二叉树为空,则空操作。
                    2. 否则:
                      1. 后序遍历左子树
                      2. 后序遍历右子树
                      3. 访问根结点

                        【实现】

                        Status PostOrderTraverse(BiTree T)
                        {
                            if(T==NULL)
                                return OK;
                            else
                            {
                                PostOrderTraverse(T->lchild);//递归遍历左子树
                                PostOrderTraverse(T->rchild);//递归遍历右子树
                                cout<<T->data;//访问根结点
                            }
                        }

                        image.gif

                        ✨遍历算法分析

                        如果去掉输出语句,从递归的角度来看,三种算法是完全相同的,或说这三种算法的访问路径是相同的,只是访问结点的实际不同。

                        【时间效率】:O(n),每个结点访问一次。

                        【空间效率】:O(n),栈占用的最大辅助空间。

                        ✨二叉树的建立

                        按照先序遍历序列建立二叉树的二叉链表。

                        例如:已知先序序列为:

                        A B C ∅ ∅ D E ∅ G ∅ ∅ F ∅ ∅ ∅

                        image.gif编辑

                        【实现】

                        void CreatBiTree(BiTree &T)
                        {
                            cin>>ch;
                            if(ch == '#')
                                T=NULL;//遇到 # 字符 递归结束,建立空树
                            else
                            {
                                T = new BiTNode;
                                T->data = ch;//生成根结点
                                CreatBiTree(T->lchild)//递归创建左子树
                                CreatBiTree(T->rchild)//递归创建右子树
                            }
                        }

                        image.gif

                        ✨遍历算法应用

                        一、计算二叉树结点总数

                        【分析】

                                如果二叉树为空树,则结点个数为0。否则,结点个数为左子树结点数+右子树结点数+1

                        【实现】

                        int NodeCount(BiTree T)
                        {
                            if(T==NULL)
                                return 0;
                            else
                            {
                                return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
                            }
                        }

                        image.gif

                        二、计算二叉树叶子结点总数

                        【分析】

                                如果二叉树为空树,则叶子结点总数为0。否则,结点总数为左子树叶子结点总数+右子树叶子结点总数

                        【实现】

                        int LeadCount(BiTree T)
                        {
                            if(T==NULL)
                                return 0;
                            if(T->lchild == NULL && T->rchild == NULL)
                                return 1;
                            else
                                return LeadCount(T->lchild) + LeadCount(T->rchild);
                        }

                        image.gif

                        三、计算二叉树的深度

                        【分析】

                                如果二叉树为空树,则叶子结点总数为0。否则,递归左子树,深度即为m。递归右子树,深度记为n,二叉树的深度为m和 n中较大者 + 1 。

                        【实现】

                        int Depth(BiTree T)
                        {
                            if(T==NULL)
                                retunr 0;
                            else
                            {
                                int m = Depth(T->lchild);
                                int n = Depth(T->rchild);
                                if(m > n)
                                    return m + 1;
                                else 
                                    return n + 1;
                            }
                        }

                        image.gif

                        重要结论:

                        若二叉树中各结点的值不同,则由二叉树的前序序列和中序序列,或由其后序序列和中序序列均能唯一的确定一颗二叉树。

                        但由前序序列和后序序列却不一定能唯一的确定一颗二叉树。

                        相关文章
                        |
                        7天前
                        |
                        算法
                        分享一些提高二叉树遍历算法效率的代码示例
                        这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
                        |
                        10天前
                        |
                        存储 缓存 算法
                        如何提高二叉树遍历算法的效率?
                        选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
                        29 5
                        |
                        14天前
                        |
                        C语言
                        【数据结构】二叉树(c语言)(附源码)
                        本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
                        63 8
                        |
                        13天前
                        |
                        机器学习/深度学习 JSON 算法
                        二叉树遍历算法的应用场景有哪些?
                        【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
                        23 0
                        |
                        1月前
                        |
                        存储 算法 关系型数据库
                        数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
                        这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
                        19 0
                        数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
                        |
                        1月前
                        |
                        存储 算法 搜索推荐
                        数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
                        这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
                        20 0
                        数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
                        |
                        1月前
                        |
                        Java
                        【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
                        【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
                        27 1
                        |
                        1月前
                        |
                        算法 Java C语言
                        【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
                        【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
                        24 1
                        |
                        1月前
                        |
                        存储
                        【数据结构】二叉树链式结构——感受递归的暴力美学
                        【数据结构】二叉树链式结构——感受递归的暴力美学
                        |
                        1月前
                        |
                        存储 算法
                        【二叉树】—— 算法题
                        【二叉树】—— 算法题
                        【二叉树】—— 算法题