二叉树(binary tree)t是有限个元素的集合(可以为空)。当二叉树非空时,其中有一个称为根的元素,余下的元素(如果有的话)被组成2个二叉树,分别称为t的左子树和右子树。
二叉树和树的区别:
在二叉树中某个元素的子树都是有序的,也就是说,可以用左,右子树来区别。而树的子树间是无序的。
满二叉树:最后一层都是叶子结点,其他各层都是左右子树的二叉树。
完全二叉树:如果一棵二叉树最多只有最后两层有度且小于2的结点,最下层的结点都集中在该层的若干位置上。 显然,满二叉树也是完全二叉树。
二叉树的存储结构:
1. 顺序存储结构(把二叉树的所有结点,按照一定的次序顺序,存储到连续的存储单元中)
对完全二叉树而言,顺序存储结构既方便访问又节省存储空间。所以这种顺序存储结构仅适用于完全二叉树)
2. 链式存储结构:
用顺序存储方式存储二叉树会造成存储空间的浪费,并且,若需要在树中经常插入和删除结点时,由于大量移动结点,顺序存储方式更是不可取的。
存储树的最自然的方式是链式方式。 表示二叉树的链表中结点至少包括3个域:数据域和左右指针域。有时为了便于找到结点的双亲,还可在结点结构中增加一个指向其双亲结点的指针域。(二叉链表或三叉链表)
定义二叉链表:
Typedef struct BTreeNode
{
TelemType data;
Struct BTreeNode * lchild;
Struct BTreeNode * rchild;
)*BTree;
二叉树的遍历:
先序,中序,后序,层次遍历。
//先序递归遍历二叉树
void PreOder(BTree T)
{
If(T==NULL)
return ; //递归出口
visite(T->data); //访问结点数据域
if(T->lchild!=NULL)
PreOder(T->lchild);
if(T->rchild!=NULL)
PreOder(T->rchild);
}
二叉树的层次遍历
void LevelOder(Btree p)
{
Sequeue a; //定义队列a用于存储同一层次的结点
p=p->root;
while(p)
{
Visit(p->data);
if(p->lchild) a->Euqueue(p->lchild);
if(p->rchild) a->Euqueue(p->rchild);
if(a.empty()) break; //若队列空,就跳出循环,层次遍历完毕
p=a->GetHead(); //否则,取出队列
a->Dequeue();
}
}
哈夫曼树及其应用
带权路径长度最短的一类树,又称最优二叉树。
带权路径长度:所有叶子结点的带权路径长度之和。
在数据通信中经常需要将转送的文字转化为二进制的0,1组成的字符串来传送。可以利用哈夫曼树构造是电文的编码总长度最短的编码方案,即以n中字符出现的次数或频率作为权,来设计哈夫曼树,得到的二进制前缀编码称为哈夫曼编码。