Huffman树,红黑树,线索二叉树

数据结构之huffman 树

带权、路径长度最短的树
路径:从树中一个结点到另一个结点之间的分支构成这两个结点间的~
路径长度:路径上的分支数
树的路径长度:从树根到每一个结点的路径长度之和
在许多应用中,常常将树中结点赋予一个有某种意义的实数,称为该结点的权。
结点的带权路径长度:是该结点到树根之间的路径长度与结点上权的乘积。
树的带权路径长度:树中所有叶子结点(k)的带权路径长度ωk lk之和, 记做WPL.

下面通过一个实例进行说明:有4个结点,权值分别为7,5,2,4,构造有4个叶子结点的二叉树


设有n个权值{w1,w2,……wn},
构造一棵有n个叶子结点的二叉树,每个叶子权值为wi,则WPL最小的二叉树叫Huffman树
哈夫曼树中没有度为1的结点,称为严格的二叉树

2. huffman算法

构造Huffman树的方法:Huffman算法

1.根据给定的n个权值{w1,w2,……wn},构造n棵只有根结点的二叉树Tj,令其权值为wj
2.在森林中选取两棵根结点权值最小的树作左右子树,构造一棵新的二叉树,置新二叉树根结点权值为其左右子树根结点权值之和
3.在森林中删除这两棵树,同时将新得到的二叉树加入森林中
4.重复上述两步,直到只含一棵树为止,这棵树即哈夫曼树

w={7,5,2,4}

构建步骤如下图所示:


3. 采用堆来构造Huffman树

顺序表中是n个权,
1。每个权生成一个仅有根的二叉链表,将根指针入堆。
2。从堆中删除2个结点,权和生成双亲结点,根入堆。
重复直2步骤n-1次。返回根指针。

解释说明:将每个权生成的仅有root的二叉链表的根指针全部入堆,这样堆顶就是最小的权,然后从堆中删除两个节点,根据堆的性质,删除的两个节点刚好就是最小的两个权值,从这两个权值构造一个双亲节点,并将root入堆,然后重复该步骤,每次都选取两个最小的权去构造新的子树,并将入堆,这样重复n-1次之后就构成了Huffman树。算法中采用了堆这个具有排序结构(优先级)的数据结构,能够很好的解决生成Huffman树的问题。

4. huffman树节点的存储结构及代码实现

 

5. Huffman树的应用:Huffman编码

数据通信用的二进制编码

思想:根据字符出现频率编码,使电文总长最短编码:

根据字符出现频率构造Huffman树,然后将树中结点引向其左孩子的分支标 “0”,引向其右孩子的分支标“1”;每个字符的编码即为从根到每个叶子的路径上得到的0、1序列

举例说明:它们的出现频率依次为4、7、5、2、9,试画出对应的哈夫曼树(请按左子树根结点的权小于等于右子树根结点的权的次序构造),并求出每个字符的哈夫曼编码


具体的编码数组结构描述如下:

typedef char datatype;
typedef struct
{
    char bits[n];
    int start;
    datatype data;
}codetype;
codetype code[n];

编码算法的基本思想:

从叶子tree[i]出发,利用双亲地址找到双亲结点tree[p],再利用tree[p]的lchild和rchild指针域判断tree[i] 是tree[p]的左孩子还是右孩子,然后决定分配代码是“0”还是“1”,然后以tree[p]为出发点继续向上回溯,直到根结点为止。

数据结构之红黑树

1. 基本概念

红黑树是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。它是在1972年由Rudolf Bayer发明的,他称之为"对称二叉B树",它现代的名字是在 Leo J. Guibas 和 Robert Sedgewick 于1978年写的一篇论文中获得的。它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。
红黑树是一种很有意思的平衡检索树。它的统计性能要好于平衡二叉树(有些书籍根据作者姓名,Adelson-Velskii和Landis,将其称为AVL-树),因此,红黑树在很多地方都有应用。在C++ STL中,很多部分(目前包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)。

2. 红黑树的性质

首先红黑树是二叉查找树,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的,所以是一种近似平衡二叉搜索树。

那么必须满足如下二叉查找树的性质:

(1).在一棵二叉查找树上,执行查找、插入、删除等操作,的时间复杂度为O(lgn)。
    因为,一棵由n个结点,随机构造的二叉查找树的高度为lgn,所以顺理成章,一般操作的执行时间为O(lgn)。
    //至于n个结点的二叉树高度为lgn的证明,可参考算法导论 第12章 二叉查找树 第12.4节。
(2).但若是一棵具有n个结点的线性链,则此些操作最坏情况运行时间为O(n)。

而红黑树能保证在最坏的情况下,基本动态几何操作时间均为O(lgn)

红黑树上每个结点内含五个域,color,key,left,right,p。如果相应的指针域没有,则设为NIL。
一般的,红黑树,满足以下性质,即只有满足以下全部性质的树,我们才称之为红黑树:
1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶结点,即空结点(NIL)是黑的。
4)如果一个结点是红的,那么它的俩个儿子都是黑的。
5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。

如图所示:


3. 树的旋转

在对红黑树进行插入和删除等操作时,对树做了修改,那么可能会违背红黑树的性质。为了保持红黑树的性质,我们可以通过对树进行旋转,即修改树种某些结点的颜色及指针结构,以达到对红黑树进行
插入、删除结点等操作时,红黑树依然能保持它特有的性质(如上文所述的,五点性质)。
 
树的旋转,分为左旋和右旋,以下借助图来做形象的解释和介绍:

(1) 左旋


(2) 右旋



数据结构之线索二叉树

1 基本概念

使用二叉链表无法直接找到每一个节点在某一种遍历序列中的前驱后继,而具有n个节点的二叉链表必定存在n+1个空链域,可以用来存放前驱和后继的指针,并称之为线索(thread),具体的作法:

若节点有左子树,则其左指针指向左孩子;否则另它指向前驱;

若节点有右子树,则其右指针指向右孩子;否则另它指向后继。

为此,二叉链表的节点结构需要增加两个标志域,指明左右链域中的指针是指向左右孩子还是指向前驱后继。

带有线索的二叉链表成为线索链表,相应的二叉树称之为线索二叉树。


2. 线索二叉树节点定义

如图所示:


对线索链表中结点的约定:在二叉链表的结点中增加两个标志域
若该结点的左子树不空,则Lchild域的指针指向其左子树且左标志域的值为“指针 Link”否则,Lchild域的指针指向其“前驱”,且左标志的值为“线索 Thread”
若该结点的右子树不空,则rchild域的指针指向其右子树,且右标志域的值为 “指针 Link”;否则,rchild域的指针指向其“后继”,且右标志的值为“线索 Thread”。
如此定义的二叉树的存储结构称作“线索链表”。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值