数据结构与算法04----树和二叉树

树和森林

  • 树:一对多的结构(可1对0,1对1,1对多),有一个起点 ‘根结点’
  • 结点:树的一个数据元素
  • 孩子:1对多里的 ‘多’
  • 子树:以某个孩子结点为根的一棵树
  • 叶子结点:没有孩子的结点
  • 森林:多棵树
    在这里插入图片描述

二叉树

  • 二叉树:每个结点至多有两个孩子(可以1个或0个),分别称为左孩子右孩子
  • 左孩子(若有)是左子树的根,右孩子(若有)是右子树的根
  • 高度(深度):最深的叶子结点所在层数 在这里插入图片描述

二叉树的重要性质

  • 第i层至多有2 ^ (i - 1)个结点
  • 高度为h的树至多有2 ^ h - 1个结点

Key1:二叉树每个结点有0或1或2个孩子,叶子结点没有孩子
Key2:二叉树的高度指从根结点向下直至最深叶子结点的高度

两种特殊二叉树

  • 满二叉树:装满的二叉树,高为h => 有2 ^ h - 1个结点在这里插入图片描述

  • 完全二叉树:只在最下一层的最右边有空缺在这里插入图片描述

Key1:满二叉树是满的,完全二叉树只是完整了,但不一定满

树/森林转换为二叉树

  • 树转为二叉树:

    • 每个结点只保留第一个孩子(老大)作为左孩子,剩下的孩子(老大的兄弟们)依次接到老大的右孩子链上
  • 森林转为二叉树:

    • 各树分别转为二叉树
    • 各树根用右孩子链相连

在这里插入图片描述

Key1:森林向二叉树转化是确定且唯一的过程

二叉树顺序存储实现

  • 顺序二叉树(底层是数组)
  • 顺序树中结点i的左右孩子分别是2i + 1和2i + 2(i从0开始计数)
  • 若结点为空,使用特殊值(如0)表示

二叉树链式实现

  • 链式树(二叉链表)
    在这里插入图片描述
/*二叉树数据结构定义*/
typedef struct TreeNode
{
	int data;
	struct TreeNode *left;
	struct TreeNode *right;
} TreeNode; 

二叉树的遍历

  • 遍历:按某种确定的次序逐个访问所有结点,时间复杂度是O(n)
  • 先序遍历:当前结点-左子树-右子树
  • 中序遍历:左子树-当前结点-右子树
  • 后序遍历:左子树-右子树-当前结点
  • *层序遍历:逐层从左向右遍历各个结点

二叉树先序/中序/后序遍历

  • 注意:右孩子是右子树的根,左孩子是左子树的根
  • 注意:一棵树是用其根结点表示的,因从根结点出发我们足以访问整棵树
    在这里插入图片描述
    在这里插入图片描述

先序遍历序列:A B C
中序遍历序列:B A C
后序遍历序列:B C A
在这里插入图片描述
先序遍历序列:3 5 4 1 9 8 2 7
中序遍历序列:5 4 1 3 8 9 2 7
后序遍历序列:1 4 5 8 7 2 9 3

Key1:二叉树三种遍历顺序中,左子树都先于右子树,区别在于访问根的次序
Key2:可以通过中序+先序/后序序列之一来还原二叉树结构,先+后则不行

哈夫曼树与哈夫曼编码

  • 先学如何构建一颗哈夫曼树,在学为什么要有哈夫曼树!
  • 初始时,一堆独立结点,结点有自己的权值
  • 重复地让当前权值最小的两个根结点作为左右孩子,生成新的根结点,新结点权值为他们的权值之和,直至形成一颗二叉树
    在这里插入图片描述
    第一步:
    在这里插入图片描述
    第二步:
    在这里插入图片描述
    第三步:
    在这里插入图片描述
    第四步:
    在这里插入图片描述
    第五步:
    在这里插入图片描述
    第六步:
    在这里插入图片描述

Why哈夫曼树?

  • 越靠近根节点,权值越大
  • 初始结点全是后来的叶子结点
  • 叶子结点权值越大,离根结点越近 => 路径越短
  • 有什么好处?如果把路径标上0和1…
  • 每一个叶子结点有一个唯一编码(不定长)
  • 思考:如果权值表示在文章中的出现频率,这种编码有什么优势?
  • 最大程度节省空间!越常用的字符码长越短。
  • 这就是哈夫曼编码
  • 题型:给一个字符-频率表,构造哈夫曼树来求哈夫曼编码表

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Len1Mi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值