根据luofang师姐还有网上做的笔记
半原创,侵删
二叉树极其重要的性质
度0结点数 = 度2结点数 +1
树的度

二叉树的性质


国际完全二叉树的定义:
1.叶子节点都在最后一层或者倒数第二层
2.如果有叶子节点,就必然有两个叶子节点
1.顺序存储
2.链式存储
Typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
中序遍历的递归算法
void InOrderTraverse(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
cout<<T->data;
InOrderTraverse(T->rchild);
}
}
至于先序和后序遍历只是调换顺序
中序遍历的非递归实现
void InOrderTraverse(BiTree &T)
{
InitStack(S);
p=T;
q=new BiTNode;
while(p||!StackEmpty(S))
{
if(p)
{
push(S,p);
p=p->lchild;
}
else
{
Pop(S,q);
cout<<q->data;
p=p->rchild;
}
}
}
先序遍历的顺序建立二叉链表
void CreatBiTree(BiTree &T)
{
ci>>ch;
if(ch=='#') T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreatBiTree(T->lchild);
CreatBiTree(T->rchild);
}
}
复制二叉树
void Copy(BiTree &T,BiTree &NewT)
{
if(T==NULL)
{
NewT=NULL;
return;
}
else
{
NewT=new BiTNode;
NewT->data=T->data;
Copy(T->lchild,NewT->lchild);
Copy(T->rchild,NewT->rchild);
}
}
计算二叉树的深度
二叉树的深度为树中节点的最大层数,二叉树的深度为左右子树深度的较大者+1
int Depth(BiTree &T)
{
if(T==NULL) return 0;
else
{
m=Depth(T->lchild);
n=Depth(T->rchild);
if(m>n)
return m+1;
else
return n+1;
}
}
统计二叉树中的节点个数
int NodeCount(BiTree &T)
{
if(T==NULL) return 0;
else
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
哈弗曼树及其应用
感觉是全网对哈夫曼树讲解最透彻的一个
从原因再到过程,再到应用 很全面!!!强推!!!
哈夫曼树:又称最优树,是指带权路径长度最短的树

哈夫曼编码:
对一颗具有n个节点的哈夫曼树,若对树中的每个左分支赋予0,右分支赋予1,则从根到每个叶子节点的路径上,各分支的赋值分别构成一个二进制串,这个二进制串就称为哈夫曼编码
前缀编码:
在一个编码方案中,任一编码都不是其他任何编码的前缀(最左子串),则称编码是前缀编码。
(这里看着很懵逼)
哈夫曼编码满足两个特征:
(1)哈夫曼编码前缀编码(也就是说,哈夫曼编码不会产生前缀的现象)也就是说,任一哈夫曼码都不会与任一其他的哈夫曼码的前缀完全发生重叠。
(2)哈夫曼编码是最优的前缀编码
例子:
例:如果需传送的电文为 ‘ABACCDA’,
它只用到四种字符,用两位二进制编码便可分辨。
假设 A, B, C, D 的编码分别为 00, 01,10, 11,则上述电文便为 ‘00010010101100’(共 14 位),译码员按两位进行分组译码,便可恢复原来的电文。
能否使编码总长度更短呢?
实际应用中各字符的出现频度不相同,用短(长)编码表示频率大(小)的字符,使得编码序列的总长度最小,使所需总空间量最少
数据的最小冗余编码问题
在上例中,若假设 A, B, C, D 的编码分别为 0,00,1,01,则电文 ‘ABACCDA’ 便为 ‘000011010’(共 9 位),但此编码存在多义性:可译为: ‘BBCCDA’、‘ABACCDA’、‘AAAACCACA’ 等。
译码的惟一性问题
要求任一字符的编码都不能是另一字符编码的前缀,这种编码称为前缀编码(其实是非前缀码)。 在编码过程要考虑两个问题,数据的最小冗余编码问题,译码的惟一性问题,利用最优二叉树可以很好地解决上述两个问题
用二叉树设计二进制前缀编码
以电文中的字符作为叶子结点构造二叉树。然后将二叉树中结点引向其左孩子的分支标 ‘0’,引向其右孩子的分支标 ‘1’; 每个字符的编码即为从根到每个叶子的路径上得到的 0, 1 序列。如此得到的即为二进制前缀编码。

例:如果需传送的电文为 ‘ABACCDA’,即:A, B, C, D 的频率(即权值)分别为 0.43, 0.14, 0.29, 0.14,试构造哈夫曼编码

例:如果需传送的电文为 ‘ABCACCDAEAE’,即:A, B, C, D, E 的频率(即权值)分别为0.36, 0.1, 0.27, 0.1, 0.18,试构造哈夫曼编码。

假设用于通信的电文仅由8个字母组成,字母在电文中出现的频率分别为0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10。
① 试为这8个字母设计赫夫曼编码。
② 试设计另一种由二进制表示的等长编码方案。
③ 对于上述实例,比较两种方案的优缺点。


线索二叉树
通过考察各种二叉链表,不管儿叉树的形态如何,空链域的个数总是多过非空链域的个数。准确的说,n各结点的二叉链表共有2n个链域,非空链域为n-1个,但其中的空链域却有n+1个。

因此,提出了一种方法,利用原来的空链域存放指针,指向树中其他结点。这种指针称为线索。
记ptr指向二叉链表中的一个结点,以下是建立线索的规则: (1)如果ptr->lchild为空,则存放指向中序遍历序列中该结点的前驱结点。这个结点称为ptr的中序前驱; (2)如果ptr->rchild为空,则存放指向中序遍历序列中该结点的后继结点。这个结点称为ptr的中序后继;

本文详细介绍了二叉树的重要性质、完全二叉树的定义,并重点探讨了哈夫曼树(最优树)的概念、哈夫曼编码的原理及应用。通过举例说明了哈夫曼编码如何实现数据的最小冗余编码,同时讨论了构建哈夫曼树的过程,以及在通信电文编码中的应用。
 -- 树&spm=1001.2101.3001.5002&articleId=112547582&d=1&t=3&u=3e03133cc0004300a3e686986f59947c)
2726

被折叠的 条评论
为什么被折叠?



