树的“应用“

目录

二叉树的性质

 3.1.1总结二叉树的度、树高、结点数等属性之间的关系

二叉树的顺序存储和基本操作实现

3.1.2 写代码:定义顺序存储的二叉树(数组实现,树的结点从数组下标1开始存储)

实现先/中/后序/层次遍历

二叉树的链式存储

树的性质 

 树(森林)的定义和画图

3.3.1写代码:使用“双亲表示法”,定义顺序存储的树(以及森林)

 3.3.2写代码:使用“孩子表示法”,定义链式存储的树(以及森林)

 3.3.3对比:树的孩子表示法存储 v.s. 图的邻接表存储 v.s. 散列表的拉链法 v.s. 基数排序。你发现了什么?

3.3.4写代码:使用“孩子兄弟表示法”,定义链式存储的树(以及森林)

 3.3.5自己动手创造,画一个结点总数不少于10的树,并画出对应的“双亲表示法、孩子表示法、孩子兄弟表示法”三种数据结构的示意图

3.3.6自己动手创造,画一个至少包含3棵树的森林,并画出对应的“双亲表示法、孩子表示法、孩子兄弟表示法”三种数据结构的示意图

哈夫曼树的应用

3.4.1自己动手创造,写10个字符,并给每个字符设置权值,画出构造哈夫曼树的过程

3.4.2用文字描述构造哈夫曼树的过程

3.4.3基于你所构造的哈夫曼树,写出10个字符的哈夫曼编码

3.4.3用文字描述根据一棵哈夫曼树“译码”的过程(即如何将二进制哈夫曼编码翻译为字符)​编辑

 并查集的应用

3.5.1写代码:定义一个并查集(用长度为n的数组实现)

3.5.2基于上述定义,实现并查集的基本操作—— 并 Union

3.5.3基于上述定义,实现并查集的基本操作—— 查 Find

 3.5.4自己设计一个例子,并查集初始有10个元素,进行若干次Union操作,画出每一次Union后的样子——(Union的优化)

 3.5.5自己设计一个例子,基于上一步得到的并查集,进行若干次find操作(每次find会进行“路径压缩”)。画出每次 find (路径压缩)后的样子——(find优化)

二叉排序树、平衡二叉树的应用题潜在考法

3.6.1自己设计一个例子,给出不少于10个关键字序列,按顺序插入一棵初始为空的二叉排序树,画出每一次插入后的样子

3.6.2基于你设计的例子,计算二叉排序树在查找成功和查找失败时的 ASL

3.6.3基于你设计的例子,依次删除不少于4个元素,画出每一次删除之后的样子(需要包含四种删除情况——删一个叶子结点、删一个只有左子树的结点、删一个只有右子树的结点、删一个既有左子树又有右子树的结点)

3.6.4 平衡二叉树

自己设计一个例子,给出不少于10个关键字序列,按顺序插入一棵初始为空的平衡二叉树,画出每一次插入后的样子(你设计的例子要涵盖LL、RR、LR、RL四种调整平衡的情况)

基于你设计的例子,计算平衡二叉树在查找成功和查找失败时的 ASL



二叉树的性质

 3.1.1总结二叉树的度、树高、结点数等属性之间的关系

性质1:在二叉树的第i层上最多有2^(i-1)个结点(i≥1)。
第一层是根结点,只有一个, 第二层有两个。 第三层有四个, 第四层有八个。

性质2:深度为k的二叉树至多有2^k-1个结点(k≥1)。
注意这里一定要看清楚,是2k后再减去1,而不是2(k-1)。以前很多同学不能完全理解,这样去记忆,就容易把性质2与性质1给弄混淆了。 深度为k意思就是有k层的二叉树,我们先来看看简单的。 如果有一层,至多1=21-1个结点。 如果有二层,至多1+2=3=22-1个结点。 如果有三层,至多1+2+4=7=23-1个结点。 如果有四层,至多1+2+4+8=15=2^4-1个结点。

二叉树的性质3:对任何一棵二叉树,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1
终端结点数其实就是叶子结点数,而一棵二叉树,除了叶子结点外,剩下的就是度为1或2的结点数了,我们设n1为度是1的结点数。则树T结点总数n=n0+n1+n2
终端结点数其实就是叶子结点数,而一棵二叉树,除了叶子结点外,剩下的就是度为1或2的结点数了,我们设n1为度是1的结点数。则树T结点总数n=n0+n1+n2 。

二叉树性质4:具有n个结点的完全二叉树的深度为|log(2^n)+1|
由满二叉树的定义我们可以知道,深度为k的满二叉树的结点数n一定是2k-1。因为这是最多的结点个数。那么对于n=2k-1倒推得到满二叉树的深度为k=log2(n+1),比如结点数为15的满二叉树,深度为4。

二叉树性质5:如果对一棵有n个结点的完全二叉树(其深度为|log(2^n)+1|)的结点按层序编号(从第一层到第层,每层从左到右),对任一结点i(1<=i<=n),有
1.如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点。
2.如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i。
3.如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1

二叉树的顺序存储和基本操作实现

3.1.2 写代码:定义顺序存储的二叉树(数组实现,树的结点从数组下标1开始存储

  1. 为了方便存储,从数组下标1开始存储数据。
  2. 树的顺序存储通常只用于存储完全二叉树(普通二叉树采用顺序存储的方式跟完全二叉树一样,但是采用这种方式的代价是浪费大量存储空间)
#define MAXSIZE 100
typedef struct treeNode{
    elemType value;    //结点中元素的值
    bool isEmpty;    //结点是否为空
}treeNode;
 
//申明一个长度为MAXSIZE的结构体数组
//由上至下、从左至右的方式存放完全二叉树的各个结点数据
treeNode T[MAXSIZE];
 
//初始化时,把结点置空
for(int i = 0; i < MAXSIZE; i++) T[i].isEmpty = true;

假设根节点的索引为1(树的结点从数组下标1开始存储)

3.1.3基于上述定义,写一个函数 int findFather ( i ) ,返回结点 i 的父节点编号

3.1.4基于上述定义,写一个函数 int leftChild ( i ) ,返回结点 i 的左孩子编号

3.1.5基于上述定义,写一个函数 int rightChild ( i ) ,返回结点 i 的右孩子编号

写代码:定义顺序存储的二叉树(数组实现,树的结点从数组下标0开始存储)

假设根节点的索引为0(树的结点从数组下标0开始存储)

左子节点的索引会是 2 i + 1 以及右子节点会是 2 i + 2,

而它的父节点(如果有)索引则为(i − 1) / 2。

基于上述定义,写一个函数 int findFather ( i ) ,返回结点 i 的父节点编号

基于上述定义,写一个函数 int leftChild ( i ) ,返回结点 i 的左孩子编号

基于上述定义,写一个函数 int rightChild ( i ) ,返回结点 i 的右孩子编号

实现先/中/后序/层次遍历

先序遍历

 中序遍历

后序遍历

 层次遍历

二叉树的链式存储

单向链:

typedef struct BiTNode{
    elemtype data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
 

双向链:双亲结点指向孩子结点,孩子结点也指向双亲结点

typedef struct BiTNode{
    struct BiTNode *lchild, *rchild, *parent;    //parent指针指向该结点的双亲结点
    int data;
}BiTNode, *BiTree;

树的性质 

 树(森林)的定义和画图

3.3.1写代码:使用“双亲表示法”,定义顺序存储的树(以及森林)

 3.3.2写代码:使用“孩子表示法”,定义链式存储的树(以及森林)

 

 3.3.3对比:树的孩子表示法存储 v.s. 图的邻接表存储 v.s. 散列表的拉链法 v.s. 基数排序。你发现了什么?

(都长这样,具体怎么描述还不知道) 

3.3.4写代码:使用“孩子兄弟表示法”,定义链式存储的树(以及森林)

 3.3.5自己动手创造,画一个结点总数不少于10的树,并画出对应的“双亲表示法、孩子表示法、孩子兄弟表示法”三种数据结构的示意图

3.3.6自己动手创造,画一个至少包含3棵树的森林,并画出对应的“双亲表示法、孩子表示法、孩子兄弟表示法”三种数据结构的示意图

哈夫曼树的应用

3.4.1自己动手创造,写10个字符,并给每个字符设置权值,画出构造哈夫曼树的过程

 

3.4.2用文字描述构造哈夫曼树的过程

3.4.3基于你所构造的哈夫曼树,写出10个字符的哈夫曼编码

3.4.3用文字描述根据一棵哈夫曼树“译码”的过程(即如何将二进制哈夫曼编码翻译为字符)

 并查集的应用

3.5.1写代码:定义一个并查集(用长度为n的数组实现)

3.5.2基于上述定义,实现并查集的基本操作—— 并 Union

 

3.5.3基于上述定义,实现并查集的基本操作—— 查 Find

 

 3.5.4自己设计一个例子,并查集初始有10个元素,进行若干次Union操作,画出每一次Union后的样子——(Union的优化)

 3.5.5自己设计一个例子,基于上一步得到的并查集,进行若干次find操作(每次find会进行“路径压缩”)。画出每次 find (路径压缩)后的样子——(find优化)

 

 

二叉排序树、平衡二叉树的应用题潜在考法

3.6.1自己设计一个例子,给出不少于10个关键字序列,按顺序插入一棵初始为空的二叉排序树,画出每一次插入后的样子

关键字序列的顺序不同,构造出的二叉排序树也可能不同

3.6.2基于你设计的例子,计算二叉排序树在查找成功和查找失败时的 ASL

【例题】:

【解答】

3.6.3基于你设计的例子,依次删除不少于4个元素,画出每一次删除之后的样子(需要包含四种删除情况——删一个叶子结点、删一个只有左子树的结点、删一个只有右子树的结点、删一个既有左子树又有右子树的结点)

 

 

3.6.4 平衡二叉树

自己设计一个例子,给出不少于10个关键字序列,按顺序插入一棵初始为空的平衡二叉树,画出每一次插入后的样子(你设计的例子要涵盖LL、RR、LR、RL四种调整平衡的情况)

基于你设计的例子,计算平衡二叉树在查找成功和查找失败时的 ASL

 

【例题】

 

 

查找成功的平均长度:ASL=(1*1+2*2+3*4)/7 = 17/7

查找失败的平均长度:ASL = (8*3)/8 = 3

 

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值