c语言,见补充代码,建立哈夫曼树c语言,请帮我找找代码错误

哈夫曼树的创建和编码浅析
哈夫曼树的创建和编码
项目忙的要死,博客停了两天,做外包的真不好受,还是做产品的强。软件最后最值钱的不是代码,而是相关的文档,文档清楚,依葫芦画瓢照做出来应该不难。项目结束了至少要整理出需求规格说明书,设计文档,用户使用说明书,开发进度表,投标书,工作说明书等文档。
本文根据《数据结构与算法》(C语言版)(第三版) 整理。
本博文作为学习资料,源代码是VC++ 6.0上可执行程序,我挪到了VS2010中执行。
1.哈夫曼树又称最优二叉树,是一类带权路径长度最短的树。
对于最优二叉树,权值越大的结点越接近树的根结点,权值越小的结点越远离树的根结点。
最优二叉树的构造算法步骤:
(1)根据给定的n个权值w1,w2,...,wn构成n棵二叉树森林F={T1,T2,...,Tn},其中每一棵二叉树Ti中都只有一个权为wi的根结点,其左、右子树为空。
(2)在森林F中选出两棵根结点权值最小的树作为一棵新二叉树的左、右子树,新二叉树的根结点的权值为其左、右子树根结点的权值之和。
(3)从F中删除这两棵二叉树,同时把新二叉树加入到F中。
(4)重复步骤(2)、(3),直到F中只含有一棵树为止,此树便为最优二叉树。
哈夫曼树的结点类型声明:
struct TreeNode
typedef struct TreeNode HFTreeN
typedef HFTreeNode HuffmanT
哈夫曼树的构造算法:
#define MaxSize 1000
//叶子数目
void Select(HuffmanTree *HT, int g, int &s1, int &s2);
void CreateHuffmanTree(HuffmanTree T[MaxSize], int n)
int i,p1,p2;
//计算哈夫曼树的结点大小
for(i=1; i&&
2.哈夫曼编码
哈夫曼编码是一种变长编码。其定义如下:
对于给定的字符集D={d1,d2,...,dn}及其频率分布F={w1,w2,...,wn},用d1,d2,...,dn作为叶结点,w1,w2,...,wn作为结点的权,利用哈夫曼算法构造一棵最优二叉树,将树中每个分支结点的左分支标上&0&;右分支标上&1&,把从根到每个叶子的路径符号(&0&或&1&)连接起来,作为该叶子的编码。
哈夫曼编码是在哈夫曼树的基础上求出来的,其基本思想是:从叶子结点di(0&=i<n)出发,向上回溯至根结点,依次求出每个字符的编码。
哈夫曼编码的回溯步骤如下:
(1)选出哈夫曼树的某一个叶子结点。
(2)利用其双亲指针parent找到其双亲结点。
(3)利用找到的双亲结点的指针域中的lchild和rchild,判断该结点是双亲的左孩子还是右孩子。若该结点是其双亲结点的左孩子,则生成代码0;若该结点是其双亲结点的右孩子,则生成代码1。
(4)由于生成的编码与要求的编码反序,将所生成的编码反序。
(5)重复步骤(1)~(4),直到所有结点都回溯完。
反序方法:首先将生成的编码从后向前依次存放在一个临时的一维数组中,并设一个指针start指示编码在该一维数组中的起始位置。当某个叶子结点的编码完成时,从临时的一维数组的start处将编码复制到该字符对应的bits中即可。
哈夫曼编码的存储结构:&
struct CodeNode
//存储字符
char bits[n+1];
//存放编码位串
typedef struct CodeNode CodeN
typedef CodeNoe HUffmanCode[n];
哈夫曼编码的算法:
void CharSetHuffmanEncoding(HuffmanTree T, HuffmanCode H)
//根据哈夫曼树T求哈夫曼编码表H
char cd[n+1];
cd[n]=&#39;\0&#39;;
for(i=0; i0)
if(T[p].lchild==c)
cd[--start]=&#39;0&#39;;
cd[--start]=&#39;1&#39;;
//继续上溯
strcpy(H[i].bits, &cd[start]);
//复制编码位串
3.哈夫曼解码
哈夫曼解码过程:从哈夫曼树的根结点出发,依次识别电文的中的二进制编码,如果为0,则走向左孩子,否则走向右孩子,走到叶结点时,就可以得到相应的解码字符。
算法如下:
void CharSetHuffmanDecoding(HuffmanTree T, char* cd, int n)
int p=2*n-2;
//从根结点开始
//当要解码的字符串没有结束时
while(cd[i]!=&#39;/0&#39;)
//当还没有到达哈夫曼树的叶子并且要解码的字符串没有结束时
while((T[p].lchild!=0 && T[p].rchild != 0) && cd[i] != &#39;\0&#39;)
if(cd[i] == &#39;0&#39;)
//如果是0,则叶子在左子树
//如果是1,则叶子在左子树
//如果到达哈夫曼树的叶子时
if(T[p].lchild == 0 && T[p].rchild == 0)
printf(&%c&, T[p].ch);
p = 2*n-1;
//如果编号为p的结点不是叶子,那么编码有错
printf(&\n解码出错! \n&);
printf(&\n&);
4.哈夫曼树的创建和哈夫曼编码程序:
在VS2010中新建Win32 控制台应用程序的项目:HuffmanTree,创建结果如下图:
// HuffmanTree.cpp : 定义控制台应用程序的入口点。
#include &stdafx.h&
typedef struct HuffmanTree
int parent, lchild,
} HuffmanT
typedef struct CodeNode
char bits[4+1];
void SelectMin(HuffmanTree tree[], int len, int * pos1, int* pos2)
int min=255;
for(i=0; itree[i].weight)
min=tree[i].
for(j=0; jtree[j].weight)
min=tree[j].
void CreateHuffmanTree(HuffmanTree tree[], int n)
int m=2*n;
for(i=n; i
Ctrl+F5执行HuffmanTree.cpp结果如下图:
</n)出发,向上回溯至根结点,依次求出每个字符的编码。&>&数据结构 哈夫曼树C语言源代码
数据结构 哈夫曼树C语言源代码
上传大小:3KB
数据结构哈夫曼树C语言源代码,很经典,备有详细注释,简单易懂,代码规范,学习数据结构的必看。
综合评分:4.6(5位用户评分)
下载个数:27
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var q = $("#form1").serializeArray();
console.log(q);
var res_area_r = $.trim($(".res_area_r").val());
if (res_area_r == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
var mess = $(".res_area_r").val();
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, _username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click",'.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
$(".res_area_r").val($.trim($(".res_area").val()));
评论共有3条
打的不错啊
可以使用,还可以
还不错,可以借鉴
审核通过送C币
6套慕课网算法视频教程
创建者:love
VS2010趣味编程视频教程
创建者:ouyongke
OMNET学习资料
上传者其他资源上传者专辑
编译原理课程设计 -----C语言编译器
数据结构层序中序遍历构建二叉树
数据结构约瑟夫环问题
数据结构迷宫穷举法求解
数据结构用队列求迷宫最短路径
课程资源热门标签
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
数据结构 哈夫曼树C语言源代码
会员到期时间:
剩余下载个数:
剩余C币:593
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
(仅够下载10个资源)
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励20下载分
被举报人:
xuanxufeng
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
数据结构 哈夫曼树C语言源代码哈夫曼的c语言实现代码
字体:[ ] 类型:转载 时间:
着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在父结点左侧,则置码为 0,若在右侧,则置码为 1。最后输出生成的编码
我们设置一个结构数组 HuffNode 保存哈夫曼树中各结点的信息。根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有 2n-1 个结点,所以数组 HuffNode 的大小设置为 2n-1 。HuffNode 结构中有 weight, lchild, rchild 和 parent 域。其中,weight 域保存结点的权值, lchild 和 rchild 分别保存该结点的左、右孩子的结点在数组 HuffNode 中的序号,从而建立起结点之间的关系。为了判定一个结点是否已加入到要建立的哈夫曼树中,可通过 parent 域的值来确定。初始时 parent 的值为 -1。当结点加入到树中去时,该结点 parent 的值为其父结点在数组 HuffNode 中的序号,而不会是 -1 了。
求叶结点的编码:该过程实质上就是在已建立的哈夫曼树中,从叶结点开始,沿结点的双亲链域回退到根结点,每回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值。由于一个字符的哈夫曼编码是从根结点到相应叶结点所经过的路径上各分支所组成的 0、1 序列,因此先得到的分支代码为所求编码的低位,后得到的分支代码为所求编码的高位码。我们可以设置一个结构数组 HuffCode 用来存放各字符的哈夫曼编码信息,数组元素的结构中有两个域:bit 和 start。其中,域 bit 为一维数组,用来保存字符的哈夫曼编码, start 表示该编码在数组 bit 中的开始位置。所以,对于第 i 个字符,它的哈夫曼编码存放在 HuffCode[i].bit 中的从 HuffCode[i].start 到 n 的 bit 位中。 代码如下:/*-------------------------------------------------------------------------&* Name:&& 哈夫曼编码源代码。&* 在 Win-TC 下测试通过&* 实现过程:着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中&*&&&&&&&&&& 自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在&*&&&&&&&&&& 父结点左侧,则置码为 0,若在右侧,则置码为 1。最后输出生成的编码。&*------------------------------------------------------------------------*/#include &stdio.h&
#define MAXBIT&&&&& 100#define MAXVALUE& 10000#define MAXLEAF&&&& 30#define MAXNODE&&& MAXLEAF*2 -1
typedef struct {&&& int bit[MAXBIT];&&&} HCodeT&&&&&&& /* 编码结构体 */typedef struct{&&&&&&&&&&&&} HNodeT&&&&&&& /* 结点结构体 */
/* 构造一颗哈夫曼树 */void HuffmanTree (HNodeType HuffNode[MAXNODE],& int n){ &&& /* i、j: 循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,&&&&&&& x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。*/&&& int i, j, m1, m2, x1, x2;&&& /* 初始化存放哈夫曼树数组 HuffNode[] 中的结点 */&&& for (i=0; i&2*n-1; i++)&&& {&&&&&&& HuffNode[i].weight = 0;&&&&&&& HuffNode[i].parent =-1;&&&&&&& HuffNode[i].lchild =-1;&&&&&&& HuffNode[i].lchild =-1;&&& } /* end for */
&&& /* 输入 n 个叶子结点的权值 */&&& for (i=0; i&n; i++)&&& {&&&&&&& printf ("Please input weight of leaf node %d: \n", i);&&&&&&& scanf ("%d", &HuffNode[i].weight);&&& } /* end for */
&&& /* 循环构造 Huffman 树 */&&& for (i=0; i&n-1; i++)&&& {&&&&&&& m1=m2=MAXVALUE;&&&& /* m1、m2中存放两个无父结点且结点权值最小的两个结点 */&&&&&&& x1=x2=0;&&&&&&& /* 找出所有结点中权值最小、无父结点的两个结点,并合并之为一颗二叉树 */&&&&&&& for (j=0; j&n+i; j++)&&&&&&& {&&&&&&&&&&& if (HuffNode[j].weight & m1 && HuffNode[j].parent==-1)&&&&&&&&&&& {&&&&&&&&&&&&&&& m2=m1; &&&&&&&&&&&&&&& x2=x1; &&&&&&&&&&&&&&& m1=HuffNode[j].&&&&&&&&&&&&&&& x1=j;&&&&&&&&&&& }&&&&&&&&&&& else if (HuffNode[j].weight & m2 && HuffNode[j].parent==-1)&&&&&&&&&&& {&&&&&&&&&&&&&&& m2=HuffNode[j].&&&&&&&&&&&&&&& x2=j;&&&&&&&&&&& }&&&&&&& } /* end for */&&&&&&&&&&& /* 设置找到的两个子结点 x1、x2 的父结点信息 */&&&&&&& HuffNode[x1].parent& = n+i;&&&&&&& HuffNode[x2].parent& = n+i;&&&&&&& HuffNode[n+i].weight = HuffNode[x1].weight + HuffNode[x2].&&&&&&& HuffNode[n+i].lchild = x1;&&&&&&& HuffNode[n+i].rchild = x2;
&&&&&&& printf ("x1.weight and x2.weight in round %d: %d, %d\n", i+1, HuffNode[x1].weight, HuffNode[x2].weight);& /* 用于测试 */&&&&&&& printf ("\n");&&& } /* end for */} /* end HuffmanTree */
int main(void){&&& HNodeType HuffNode[MAXNODE];&&&&&&&&&&& /* 定义一个结点结构体数组 */&&& HCodeType HuffCode[MAXLEAF],&&&&&&& /* 定义一个编码结构体数组, 同时定义一个临时变量来存放求解编码时的信息 */&&& int i, j, c, p,&&& printf ("Please input n:\n");&&& scanf ("%d", &n);&&& HuffmanTree (HuffNode, n);&&& for (i=0; i & i++)&&& {&&&&&&& cd.start = n-1;&&&&&&& c =&&&&&&& p = HuffNode[c].&&&&&&& while (p != -1)&& /* 父结点存在 */&&&&&&& {&&&&&&&&&&& if (HuffNode[p].lchild == c)&&&&&&&&&&&&&&& cd.bit[cd.start] = 0;&&&&&&&&&&& else&&&&&&&&&&&&&&& cd.bit[cd.start] = 1;&&&&&&&&&&& cd.start--;&&&&&&& /* 求编码的低一位 */&&&&&&&&&&& c=p;&&&&&&&&&&&&&&&&&&& &&&&&&&&&&& p=HuffNode[c].&&& /* 设置下一循环条件 */&&&&&&& } /* end while */&&&&&&& /* 保存求出的每个叶结点的哈夫曼编码和编码的起始位 */&&&&&&& for (j=cd.start+1; j&n; j++)&&&&&&& { HuffCode[i].bit[j] = cd.bit[j];}&&&&&&& HuffCode[i].start = cd.&&& } /* end for */&&& /* 输出已保存好的所有存在编码的哈夫曼编码 */&&& for (i=0; i&n; i++)&&& {&&&&&&& printf ("%d 's Huffman code is: ", i);&&&&&&& for (j=HuffCode[i].start+1; j & j++)&&&&&&& {&&&&&&&&&&& printf ("%d", HuffCode[i].bit[j]);&&&&&&& }&&&&&&& printf ("\n");&&& }&&& getch();&&& return 0;}
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具}

我要回帖

更多关于 c语言代码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信