- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C语言实现哈夫曼树由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例为大家分享了C语言实现哈夫曼树的具体代码,供大家参考,具体内容如下 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
//哈夫曼树C语言实现
#include <stdio.h>
#include <stdlib.h>
typedef
struct
HuffmanNode
{
char
letter;
//存储的字符,叶节点为字母,非叶节点为#
struct
HuffmanNode *parent;
//父亲结点
int
code;
//如果为父亲结点的左孩子,则为0,右孩子为1
}HuffmanNode;
typedef
struct
HeapNode
{
int
rate;
//出现频率
HuffmanNode *node;
//对应于哈夫曼树中的结点
}HeapNode;
/*------------------全局变量----------------------*/
int
heapSize;
//堆大小
int
num;
//记录字符数量
HeapNode *heap;
//堆数组
char
*letter;
//字符数组
int
*rate;
//字符出现频率
HuffmanNode **array;
//记录叶节点的数组,打印编码的时候可以从叶结点回溯向上
char
ch;
/*----------------------函数声明-------------------------*/
void
init(
int
numOfLetters);
//初始化变量
void
input();
//输入数组
int
parent(
int
i);
//求父节点
int
left(
int
i);
//求左孩子
int
right(
int
i);
//求右孩子
void
swap(
int
i,
int
j);
//交换函数
void
heapIfy(
int
i,
int
localHeapSize);
//维持堆性质函数,使用前提为左右子树均为最小堆
void
buildHeap();
//初始化堆
HeapNode* extractMin();
//去掉并返回堆中最小的元素
void
heapInsert(
int
rate,HuffmanNode *p);
//向堆中插入数据(前提:堆已经初始化)
HuffmanNode* buildTree();
//构造哈夫曼树
void
display();
//显示函数
void
backPrint(HuffmanNode *p,HuffmanNode *root);
//从叶节点回溯打印编码code
/*----------------------函数实现-------------------------*/
void
init(
int
numOfLetters)
{
heapSize=numOfLetters;
//堆大小初始化为字母数
num=numOfLetters;
//记录字符数量
heap=(HeapNode*)
malloc
((numOfLetters+1)*
sizeof
(HeapNode));
//分配堆空间,最多只需要字符的个数,因为合并过程中删除两个,插入一个
letter=(
char
*)
malloc
((numOfLetters+1)*
sizeof
(
char
));
//用于存储字符
rate=(
int
*)
malloc
((numOfLetters+1)*
sizeof
(
int
));
//用于存储字符出现频率
array=(HuffmanNode **)
malloc
((numOfLetters+1)*
sizeof
(HuffmanNode));
//记录叶节点的数组,打印编码的时候可以从叶结点回溯向上
}
void
input()
{
int
i=1;
while
(i<=heapSize)
{
printf
(
"输入第%d个字符\n"
,i);
scanf
(
"%c"
,&letter[i]);ch=
getchar
();
printf
(
"输入第%d个字符的频度\n"
,i);
scanf
(
"%d"
,&rate[i]);ch=
getchar
();
//向堆中插入各个结点
heap[i].rate=rate[i];
heap[i].node=(HuffmanNode *)
malloc
(
sizeof
(HuffmanNode));
array[i]=heap[i].node;
heap[i].node->parent=NULL;
heap[i].node->letter=letter[i];
i++;
}
}
int
parent(
int
i)
{
return
i/2;
}
int
left(
int
i)
{
return
2*i;
}
int
right(
int
i)
{
return
2*i+1;
}
void
swap(
int
i,
int
j)
//交换结构体数组,需要交换结构体内数据
{
int
rate;
HuffmanNode *p;
rate=heap[i].rate;
p=heap[i].node;
heap[i].rate=heap[j].rate;
heap[i].node=heap[j].node;
heap[j].rate=rate;
heap[j].node=p;
}
void
heapIfy(
int
i,
int
localHeapSize)
//维持堆性质函数,使用前提为左右子树均为最小堆
{
int
l=left(i);
int
r=right(i);
int
least=i;
//找出heap成员rate 的i,left(i),right(i)的最小值
if
(l<=localHeapSize&&heap[least].rate>heap[l].rate)
{
least=l;
}
if
(r<=localHeapSize&&heap[least].rate>heap[r].rate)
{
least=r;
}
if
(least!=i)
{
swap(i,least);
heapIfy(least,localHeapSize);
}
}
void
buildHeap()
//初始化堆
{
int
i=0;
for
(i=heapSize/2;i>=1;i--)
{
heapIfy(i,heapSize);
}
}
HeapNode* extractMin()
{
if
(heapSize>=1)
{
HeapNode *min;
swap(1,heapSize);
min=&heap[heapSize];
--heapSize;
heapIfy(1,heapSize);
return
min;
}
else
{
printf
(
"堆中没有元素"
);
return
NULL;
}
}
void
heapInsert(
int
rate,HuffmanNode *p)
{
++heapSize;
int
i=heapSize;
while
(i>1&&heap[parent(i)].rate>rate)
{
heap[i].rate=heap[parent(i)].rate;
heap[i].node=heap[parent(i)].node;
i=parent(i);
}
heap[i].rate=rate;
heap[i].node=p;
}
HuffmanNode* buildTree()
{
buildHeap();
//初始化堆
HeapNode *p;
//用于临时存储最小堆结点
HeapNode *q;
//用于临时存储次小堆结点
int
count=heapSize;
int
i;
for
(i=1;i<=count-1;i++)
{
HuffmanNode *tree=(HuffmanNode*)
malloc
(
sizeof
(HuffmanNode));
//生成内结点
tree->letter=
'#'
;
//内结点的字符记作#,没有实际意义
p=extractMin();
q=extractMin();
p->node->parent=tree;
p->node->code=0;
q->node->parent=tree;
q->node->code=1;
//printf("%c:%d",p->node->letter,p->node->code);
//printf("\n"); printf("%c:%d",q->node->letter,q->node->code); printf("\n");//测试
heapInsert(p->rate+q->rate,tree);
//插入堆中
}
return
extractMin()->node;
}
void
display()
{
HuffmanNode*p=buildTree();
////哈夫曼树的根节点地址
int
i=1;
while
(i<=num)
{
printf
(
"%c:"
,array[i]->letter);
backPrint(array[i],p);
printf
(
"\n"
);
i++;
}
}
void
backPrint(HuffmanNode *p,HuffmanNode *root)
{
if
(p!=root)
{
backPrint(p->parent,root);
printf
(
"%d"
,p->code);
//printf("++++");//测试
}
}
int
main(
int
argc ,
char
* argv[])
{
int
number;
printf
(
"输入的字符个数为:\n"
);
scanf
(
"%d"
,&number);
ch=
getchar
();
init(number);
input();
display();
system
(
"PAUSE"
);
return
0;
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://blog.csdn.net/whoami_2011/article/details/7085029 。
最后此篇关于C语言实现哈夫曼树的文章就讲到这里了,如果你想了解更多关于C语言实现哈夫曼树的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
关于 B 树与 B+ 树,网上有一个比较经典的问题:为什么 MongoDb 使用 B 树,而 MySQL 索引使用 B+ 树? 但实际上 MongoDb 真的用的是 B 树吗?
如何将 R* Tree 实现为持久(基于磁盘)树?保存 R* 树索引或保存叶值的文件的体系结构是什么? 注意:此外,如何在这种持久性 R* 树中执行插入、更新和删除操作? 注意事项二:我已经实现了一个
目前,我正在努力用 Java 表示我用 SML 编写的 AST 树,这样我就可以随时用 Java 遍历它。 我想知道是否应该在 Java 中创建一个 Node 类,其中包含我想要表示的数据,以及一个数
我之前用过这个库http://www.cs.umd.edu/~mount/ANN/ .但是,它们不提供范围查询实现。我猜是否有一个 C++ 范围查询实现(圆形或矩形),用于查询二维数据。 谢谢。 最佳
在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择
书接上回,今天和大家一起动手来自己实现树。 相信通过前面的章节学习,大家已经明白树是什么了,今天我们主要针对二叉树,分别使用顺序存储和链式存储来实现树。 01、数组实现 我们在上一节中说过,
书节上回,我们接着聊二叉树,N叉树,以及树的存储。 01、满二叉树 如果一个二叉树,除最后一层节点外,每一层的节点数都达到最大值,即每个节点都有两个子节点,同时所有叶子节点都在最后一层,则这个
树是一种非线性数据结构,是以分支关系定义的层次结构,因此形态上和自然界中的倒挂的树很像,而数据结构中树根向上树叶向下。 什么是树? 01、定义 树是由n(n>=0)个元素节点组成的
操作系统的那棵“树” 今天从一颗 开始,我们看看如何从小树苗长成一颗苍天大树。 运转CPU CPU运转起来很简单,就是不断的从内存取值执行。 CPU没有好好运转 IO是个耗费时间的活,如果CPU在取值
我想为海洋生物学类(class)制作一个简单的系统发育树作为教育示例。我有一个具有分类等级的物种列表: Group <- c("Benthos","Benthos","Benthos","Be
我从这段代码中删除节点时遇到问题,如果我插入数字 12 并尝试删除它,它不会删除它,我尝试调试,似乎当它尝试删除时,它出错了树的。但是,如果我尝试删除它已经插入主节点的节点,它将删除它,或者我插入数字
B+ 树的叶节点链接在一起。将 B+ 树的指针结构视为有向图,它不是循环的。但是忽略指针的方向并将其视为链接在一起的无向叶节点会在图中创建循环。 在 Haskell 中,如何将叶子构造为父内部节点的子
我在 GWT 中使用树控件。我有一个自定义小部件,我将其添加为 TreeItem: Tree testTree = new Tree(); testTree.addItem(myWidget); 我想
它有点像混合树/链表结构。这是我定义结构的方式 struct node { nodeP sibling; nodeP child; nodeP parent; char
我编写了使用队列遍历树的代码,但是下面的出队函数生成错误,head = p->next 是否有问题?我不明白为什么这部分是错误的。 void Levelorder(void) { node *tmp,
例如,我想解析以下数组: var array1 = ["a.b.c.d", "a.e.f.g", "a.h", "a.i.j", "a.b.k"] 进入: var json1 = { "nod
问题 -> 给定一棵二叉树和一个和,确定该树是否具有从根到叶的路径,使得沿路径的所有值相加等于给定的和。 我的解决方案 -> public class Solution { public bo
我有一个创建 java 树的任务,它包含三列:运动名称、运动类别中的运动计数和上次更新。类似的东西显示在下面的图像上: 如您所见,有 4 种运动:水上运动、球类运动、跳伞运动和舞蹈运动。当我展开 sk
我想在 H2 数据库中实现 B+ Tree,但我想知道,B+ Tree 功能在 H2 数据库中可用吗? 最佳答案 H2 已经使用了 B+ 树(PageBtree 类)。 关于mysql - H2数据库
假设我们有 5 个字符串数组: String[] array1 = {"hello", "i", "cat"}; String[] array2 = {"hello", "i", "am"}; Str
我是一名优秀的程序员,十分优秀!