哈夫曼树的构建(C语言)
哈夫曼树的构建(C语言)
算法思路:
主要包括两部分算法,一个是在数组中找到权值最小、且无父结点两个结点位置,因为只有无父结点才能继续组成树; 另一个就是根据这两个结点来修改相关结点值。
结构定义和头文件
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#define OVERFLOW -1
typedef struct {
int weight;//结点权值
int lchild, rchild, parent;//结点左、右孩子、父结点
}HNode,*HTree;在数组中找到目前权值最小的两个结点 由于哈夫曼树规定结点左子树权值小于右子树,所以我这里把权值较小的那个结点位置赋给p1
这部分我先找到前两个无父结点的结点位置赋给p1和p2,再继续遍历之后的与当前的p1和p2位置的结点权值比较
若结点有父结点,直接跳过
若结点无父结点,且权值小于p1,则将该位置赋给p1,令p2等于之前的p1
若结点无父结点,且权值大于p1、小于p2,则将该位置赋给p2
void selectMin(HTree HT,int length, int* p1, int* p2) {//搜索当前数组中无父结点的权值最小的两个结点的下标
int i = ;//数组下标从1开始,0不用
while (HT[i].parent!= && i <= length)//遍历到第一个无父结点的结点位置
i++;
*p1 = i; i++;
while (HT[i].parent!= && i <= length)//遍历到第二个无父结点的结点位置
i++;
*p2 = i; i++;
if (HT[*p1].weight > HT[*p2].weight) {//令p1始终指向较小权值的结点位置
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
for (int n = i; n <= length; n++) {//继续遍历,比较之后的无父结点的结点权值与p1、p2
if (HT[n].parent != )//若该结点有父结点,直接跳过
continue;
else if (HT[n].weight < HT[*p1].weight) {//若该结点权值小于p1,令p1等于n,p2等于p1
*p2 = *p1;
*p1 = n;
}
else if (HT[n].weight > HT[*p1].weight&& HT[n].weight < HT[*p2].weight)//若该结点权值大于p1,小于p2,令*p2=n
*p2 = n;
}
return;
}构建哈夫曼树
void createHuffmanTree() {//构建哈夫曼树
int lnode;//哈夫曼树叶子结点数
printf("input leafnode number:");
scanf_s("%d", &lnode);
int length=*lnode-;//哈夫曼树结点数=2*叶子节点数-1
HTree HT = (HTree)malloc(sizeof(HNode) * (length + ));//数组下标从1开始,所以分配(length+1)大小空间
if (!HT) exit(OVERFLOW);
memset(HT, , sizeof(HNode) * (length + ));//将数组内元素都初始化为0
HTree p = HT;
for (int i = lnode + ; i <=length; i++) {//把所有非叶子节点的结点权值规定为无穷大,否则会影响接下来选择结点最小值
(p + i)->weight = ;
}
printf("input leafnode weight:");
for (int i = ; i <= lnode; i++) {//输入叶子结点权值
scanf_s("%d", &(p+i)->weight);
}
int p1, p2;
for (int i = lnode+; i <= length; i++) {//从第一个非叶子结点开始遍历
selectMin(p, length, &p1, &p2);
(p + i)->lchild = p1;//修改左子树的值
(p + i)->rchild = p2;//修改左子树的值
(p + i)->weight = (p + p1)->weight + (p + p2)->weight;//修改权值
(p + p1)->parent = i;//修改左子树的父结点值
(p + p2)->parent = i;//修改右子树的父结点值
}
for (int i = ; i <= length; i++) {
printf("%3d %3d %3d %3d %3d\n", i, (p + i)->weight, (p + i)->parent, (p + i)->lchild, (p + i)->rchild);//遍历输出
}
return;
}主函数及具体实例
int main() {
createHuffmanTree();
return ;
}
自我总结
写这部分时候动态数组分配和使用那里耗了点时间,主要原因还是不太熟以及vs的操作太迷了。经过这次训练又加深了一点理解,vs的调试也逐渐能够熟练使用了,还是挺开心的。
哈夫曼树的构建(C语言)的更多相关文章
- 哈夫曼树(一)之 C语言详解
本章介绍哈夫曼树.和以往一样,本文会先对哈夫曼树的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现:实现的语言虽不同,但是原理如出一辙,选择其中之一进行了解即可.若 ...
- 【算法】赫夫曼树(Huffman)的构建和应用(编码、译码)
参考资料 <算法(java)> — — Robert Sedgewick, Kevin Wayne <数据结构> ...
- Android版数据结构与算法(七):赫夫曼树
版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 近期忙着新版本的开发,此外正在回顾C语言,大部分时间没放在数据结构与算法的整理上,所以更新有点慢了,不过既然写了就肯定尽力将这部分完全整理好分享出 ...
- 【数据结构】赫夫曼树的实现和模拟压缩(C++)
赫夫曼(Huffman)树,由发明它的人物命名,又称最优树,是一类带权路径最短的二叉树,主要用于数据压缩传输. 赫夫曼树的构造过程相对比较简单,要理解赫夫曼数,要先了解赫夫曼编码. 对一组出现频率不同 ...
- Python---哈夫曼树---Huffman Tree
今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...
- 数据结构-哈夫曼树(python实现)
好,前面我们介绍了一般二叉树.完全二叉树.满二叉树,这篇文章呢,我们要介绍的是哈夫曼树. 哈夫曼树也叫最优二叉树,与哈夫曼树相关的概念还有哈夫曼编码,这两者其实是相同的.哈夫曼编码是哈夫曼在1952年 ...
- 高级数据结构---赫(哈)夫曼树及java代码实现
我们经常会用到文件压缩,压缩之后文件会变小,便于传输,使用的时候又将其解压出来.为什么压缩之后会变小,而且压缩和解压也不会出错.赫夫曼编码和赫夫曼树了解一下. 赫夫曼树: 它是一种的叶子结点带有权重的 ...
- Java实现WUST 1002: 哈夫曼树
[问题描述] 根据给定的若干权值可以构造出一颗哈夫曼树.构造的哈夫曼树可能不唯一,但是按照下面的选取原则所构造出来的哈夫曼树应该是唯一的. (1)每次选取优先级最低的两个结点,优先级最低的作为左子树, ...
- C++ 漫谈哈夫曼树
1. 前言 什么是哈夫曼树? 把权值不同的n个结点构造成一棵二叉树,如果此树满足以下几个条件: 此 n 个结点为二叉树的叶结点 . 权值较大的结点离根结点较近,权值较小的结点离根结点较远. 该树的带权 ...
随机推荐
- Java内功心法,创建型设计模式包括哪些
1. 单例(Singleton) Intent 确保一个类只有一个实例,并提供该实例的全局访问点. Class Diagram 使用一个私有构造函数.一个私有静态变量以及一个公有静态函数来实现. 私有 ...
- Flutter 徐徐图之(一)—— 从搭建开发环境到 Hello World
一.环境变量 由于众所周知的原因,在国内访问 Flutter 有时可能会受到限制,所以在开发之前,需要先配置环境变量 MacOS: 编辑 ~/.bash_profile 文件 vim ~/.bash_ ...
- 来自数组原型 Array.prototype 的遍历函数
1. Array.prototype.forEach() forEach() 是一个专为遍历数组而生的方法,它没有返回值,也不会改变原数组,只是简单粗暴的将数组遍历一次 参数: callback() ...
- OKHttp和NumberProgressbar组建强大的Android版本更新功能
你们看过韩国电影<奇怪的她>不?女主角是不是超级漂亮的.......好啦,扯正事吧,先看看女神照片. 公司新项目用到了OKHttp网络框架,在下载文件这块都蒙圈啦,再查查资料就一个Reso ...
- Android 一个TextView中设置多种不同大小的字体,设置超链接
以前项目中要是遇到这样的UI设计,都是傻不拉唧的分为三个TextView来实现,今天在微信中无意中看了一篇公众号文章,发现原来只要一个TextView就可以搞定啦,人生最悲哀的事情莫过于工作了这么久啦 ...
- vue开发环境配置
一.开发工具 Visual Studio Code 二.环境搭建 vue推荐开发环境: Node.js: javascript运行环境(runtime),不同系统直接运行各种编程语言 npm: Nod ...
- Linux shell if条件判断1
shell 逻辑控制语句: 分支判断结构 if case 循环结构 for while unt ...
- Linux的yum管理
前面介绍了软件的管理的方式rpm.但有个缺点,rpm不能解决依赖. 下面介绍的yum软件管理.可以完美的解决这个问题. 使用yum的方式管理rpm软件 优势:自动解决软件的依赖关系 ...
- linuxIP地址配置字段说明
虚拟机网络适配器改成桥接 vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 设备名称 BOOTPROTO=dhcp /static 自动 ...
- CDH6.1.1阿里云安装实践
概念介绍 CDH概览 CDH是Apache Hadoop和相关项目的最完整.最受测试和最流行的发行版.CDH提供Hadoop的核心元素-可伸缩存储和分布式计算-以及基于web的用户界面和重要的企业功能 ...