【C语言数据结构(基础版)】第五站:树和二叉树(下)

简介: 【C语言数据结构(基础版)】第五站:树和二叉树

这就是我们的大致思路,而要实现这个首先,我们得导入我们队列,导入之后,我们需要修改的部分就是这两个,前置声明,因为我们的树是在他的里面定义的,所以在队列的头文件里面是不认识树结点的,所以我们得先声明一下,定义就在后面让他去找去。

 所以他最终的代码为

//层序遍历
void LevelOrder(BTNode* root)
{
  Queue q;
  QueueInit(&q);
  if (root != NULL)
  {
    QueuePush(&q, root);
  }
  while (!QueueEmpty(&q))
  {
    BTNode* front = QueueFront(&q);
    QueuePop(&q);
    printf("%c ", front->date);
    if (root->left != NULL)
    {
      QueuePush(&q, front->left);
    }
    if (root->right != NULL)
    {
      QueuePush(&q, front->right);
    }
  }
  printf("\n");
  QueueDestory(&q);
}

运行结果为

5.二叉树的销毁

想要销毁这颗二叉树,那么我们就必须得使用后序的方式来进行销毁,如果根节点是NULL,那么什么也不用做,如果不是空,那么就先销毁他的左子树,然后销毁右子树,最后销毁该结点。如此递归下去即可,代码如下

void DestoryTree(BTNode* root)
{
  if (root == NULL)
  {
    return;
  }
  DestoryTree(root->left);
  DestoryTree(root->right);
  free(root);
  root = NULL;
}

6.二叉树的一些选择题

1.某完全二叉树按层次输出(同一层从左到右)的序列为 ABCDEFGH 。该完全二叉树的前序序列为( )

A、 ABDHECFG         B、 ABCDEFGH         C、 HDBEAFCG         D、 HDEBFGCA

对于这道题,最关键的部分是完全二叉树这几个字眼。由此我们直接得出该完全二叉树的图

而他的先序遍历我们很容易就得知,A B D H E C F G

所以选A

2.二叉树的先序遍历和中序遍历如下:先序遍历:EFHIGJK;中序遍历:HFIEJKG.则二叉树根结点为 ()

A、E         B、 F         C、 G         D、 H

对于这道题其实不用中序遍历我们也能做出来,因为我们知道先序遍历第一个肯定是根节点,所以就直接得出答案为E

但是呢我们也要知道先序遍历和中序遍历其实是可以确定一个二叉树的。我们现在画出他的二叉树,首先先序遍历我们可以确定根,所以我们知道首先有一个根E,有了根以后,我们根据这个根在中序遍历中的位置就能确定出左右区间,所以HFI部分为左子树,JKG部分为右子树。而HFI这一部分我们又回到先序遍历中,我们可以看出F是根,我们由这个F是根又回到中序遍历中确定他的左右子树区间,我们不难得出,H就是F的左子树,I就是F的右子树。同理,我们可以得出JKG部分的结构,G为根节点,J和K都是左子树部分,而JK部分中,J又是根节点,而K 是J 的右子树

最终我们得出这颗二叉树为

3.设一课二叉树的中序遍历序列:badce,后序遍历序列:bdeca,则二叉树前序遍历序列为____。

A、 adbce         B、 decab         C、 debac         D、 abcde

这道题和上一道题是一样的,我们可以根据中序遍历和后序写出他的二叉树。这里直接给出他的二叉树

所以他的先序遍历为abcde

7.牛客题目之二叉树遍历

在这里也给出一道题

题目链接:二叉树遍历_牛客题霸_牛客网

题目描述:

(1)思路分析

首先我们先将思路给理清楚,二叉树的中序遍历并不难,难的是如何根据输入的字符串去构建二叉树。他的构建过程是这样的,因为他是根据先序遍历来构建的,那么第一个a肯定就是根结点,然后第二个b就是左子树的根节点,如此下来,c也是b的左子树的根结点,这时候我们该看c的左子树了,但是下一个数据是#,也就是说c的左子树是一个空,那么就该插入c的右子树了,而这个右子树恰好也是一个空。所以就返回到b的右子树了,b的右子树是一个d,d的左子树是一个e,e的左子树又是空,e的右子树是g,g的左右子树都是空。所以现在回到了d的右子树了,d的右子树刚好是一个f,而f的左右子树都是空,所以现在回到了a,a的右子树是一个空。

这样一来二叉树就构建完成了,如下图所示

有了二叉树构建完成,那么这道题简直就是易如反掌了

(2)解题代码

#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode
{
    struct TreeNode* left;
    struct TreeNode* right;
    char val;
}TreeNode;
TreeNode* CreateTree(char* str,int* i)
{
    if(str[*i]=='#')
    {
        (*i)++;
        return NULL;
    }
    TreeNode* root=(TreeNode*)malloc(sizeof(TreeNode));
    if(root==NULL)
    {
        printf("malloc fail\n");
        exit(-1);
    }
    root->val=str[*i];
    (*i)++;
    root->left=CreateTree(str,i);
    root->right=CreateTree(str,i);
    return root;
}
void InOrder(TreeNode* root)
{
    if(root==NULL)
    {
        return ;
    }
    InOrder(root->left);
    printf("%c ",root->val);
    InOrder(root->right);
}
int main() 
{
    char str[101]={0};
    scanf("%s",str);
    int i=0;
    TreeNode* root = CreateTree(str,&i);
    InOrder(root);
    return 0;
}

四、哈夫曼树的建立以及编码

在这里也简单提及一下哈夫曼树,实际上哈夫曼树应用并不多。一般只应用于文件压缩。在这里简单的提及一下哈夫曼树的建立以及他的编码

假设我们有如下四个结点,a、b、c、d相当于他们的编号,7、5、2、4则是他们的权值,我们利用这四个结点来构造一颗哈夫曼树

我们的构造过程是这样的,先找出最小的和次最小的两个结点,然后让最小的放在左边,次最小的放在右边,然后再他们这两个结点上面构造一个双亲结点。这个双亲结点的权值是他们两个的权值之和

然后接下来将这个6这个结点和剩余的结点放在一块,找出他们的最小的两个结点,同样最小的放在左边,次最小的放在右边

跟上面同样的道理,继续将剩余的找出最小的两个

这样一来,我们就构建出哈夫曼树了,上面的就是哈夫曼树

有了哈夫曼树,我们还会对其进行编码,我们将每一个左子树编码为0,右子树编码为1

有了这些编码,我们就可以知道每一个结点的编码是多少了

比如a的编码为0、b的编码为10、c的编码为110、d的编码为111

而这些编码就是哈夫曼编码

这棵树也叫做加权路径最优二叉树,也就是所有原结点的权值*路径长度和最小

即:权值越大、路径越短、编码越短;权值越小、路径越长、编码越长。


总结

本小节讲解了树的概念,二叉树的性质,二叉树的先序中序后序层序遍历以及计算叶子结点,总结点个数的实现,最后还有哈夫曼树的建立以及编码

如果对你有帮助,不要忘记点赞加收藏哦!!!

想获得更多优质的内容, 一定不要忘记关注我哦!!!

相关文章
|
2月前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
58 1
|
2月前
|
存储 算法 搜索推荐
【趣学C语言和数据结构100例】91-95
本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。
57 4
|
2月前
|
存储 机器学习/深度学习 搜索推荐
【趣学C语言和数据结构100例】86-90
本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
50 4
|
2月前
|
存储 算法 数据处理
【趣学C语言和数据结构100例】81-85
本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
54 4
|
2月前
|
算法 数据可视化 数据建模
【趣学C语言和数据结构100例】76-80
本文介绍了五种图论算法的C语言实现,涵盖二叉树的层次遍历及广度优先搜索(BFS)和深度优先搜索(DFS)的邻接表与邻接矩阵实现。层次遍历使用队列按层访问二叉树节点;BFS利用队列从源节点逐层遍历图节点,适用于最短路径等问题;DFS通过递归或栈深入图的分支,适合拓扑排序等场景。这些算法是数据结构和算法学习的基础,对提升编程能力和解决实际问题至关重要。
55 4
|
2月前
|
存储 算法 vr&ar
【趣学C语言和数据结构100例】71-75
本文介绍了五个C语言数据结构问题及其实现,涵盖链表与二叉树操作,包括按奇偶分解链表、交换二叉树左右子树、查找节点的双亲节点、计算二叉树深度及求最大关键值。通过递归和遍历等方法,解决了理论与实际应用中的常见问题,有助于提升编程能力和数据结构理解。
47 4
|
2月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】66-70
本书《趣学C语言和数据结构100例》精选了5个典型的数据结构问题及C语言实现,涵盖链表与数组操作,如有序集合的集合运算、有序序列表的合并、数组中两顺序表位置互换、三递增序列公共元素查找及奇偶数重排。通过详细解析与代码示例,帮助读者深入理解数据结构与算法设计的核心思想,提升编程技能。
37 4
|
13天前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
74 5
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
68 1