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

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

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

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

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

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


📚目录

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

📝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

                        重要结论:

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

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

                        相关文章
                        |
                        14天前
                        |
                        存储 机器学习/深度学习
                        【数据结构】二叉树全攻略,从实现到应用详解
                        本文介绍了树形结构及其重要类型——二叉树。树由若干节点组成,具有层次关系。二叉树每个节点最多有两个子树,分为左子树和右子树。文中详细描述了二叉树的不同类型,如完全二叉树、满二叉树、平衡二叉树及搜索二叉树,并阐述了二叉树的基本性质与存储方式。此外,还介绍了二叉树的实现方法,包括节点定义、遍历方式(前序、中序、后序、层序遍历),并提供了多个示例代码,帮助理解二叉树的基本操作。
                        38 13
                        【数据结构】二叉树全攻略,从实现到应用详解
                        |
                        11天前
                        |
                        存储 算法 C语言
                        数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
                        本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
                        |
                        11天前
                        |
                        存储 机器学习/深度学习 C语言
                        数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
                        本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。
                        |
                        11天前
                        |
                        存储 C语言
                        数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
                        本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。
                        |
                        1月前
                        |
                        存储
                        【初阶数据结构篇】二叉树基础概念
                        有⼀个特殊的结点,称为根结点,根结点没有前驱结点。
                        |
                        1月前
                        |
                        存储 Linux Windows
                        【数据结构】二叉树
                        【数据结构】二叉树
                        |
                        1月前
                        |
                        存储 算法 Linux
                        【数据结构】树、二叉树与堆(长期维护)(1)
                        【数据结构】树、二叉树与堆(长期维护)(1)
                        |
                        1月前
                        |
                        算法
                        【数据结构】树、二叉树与堆(长期维护)(2)
                        【数据结构】树、二叉树与堆(长期维护)(2)
                        【数据结构】树、二叉树与堆(长期维护)(2)
                        |
                        1月前
                        |
                        算法 Java
                        数据结构二叉树
                        这篇文章讨论了数据结构中的二叉树,并提供了一个二叉树中序遍历的算法示例,包括给定二叉树的根节点返回中序遍历结果的Java代码实现。
                        数据结构二叉树
                        |
                        2月前
                        |
                        存储
                        【数据结构】树和二叉树的概念及结构
                        数据结构——树和二叉树的概念及结构
                        58 3
                        【数据结构】树和二叉树的概念及结构

                        热门文章

                        最新文章