IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 哈夫曼树和哈夫曼编码解析,附源码(C实现) -> 正文阅读

[数据结构与算法]哈夫曼树和哈夫曼编码解析,附源码(C实现)

1.哈夫曼树

1.1概念

通俗来讲,就是在一堆数字中,选取最小的两个当叶子节点,他们的加和为他们的父结点。

如图:

至于怎么构造这看自己心情,因为二叉树得到构造不唯一,这也是它同权不同构的特点。如果是字符A,B,C,D....就看每种字符出现的频率!

1.2创建哈夫曼树

1.21 哈夫曼树结构

typedef struct {
	int weight;
	int parent,lchild,rchild;
}HTNode,HuffmanTree[M+1];

1.22 挑选最小两个权值函数

判断中,父节点的判断起筛选作用,目的是排除已经选过的值

typedef struct {   //定义一个结构体  更直观
	int falg1;
	int falg2;
}MIN;

//挑选 2 个权值最小的结点
MIN select (HuffmanTree ht,int len){
	int k=1;
	MIN check; 
	int min1,min2,falg1,falg2;
	min1=100;
	min2=100;
	//目的是 s1 的权值要不大于 s2 的权值
	for(k;k<=len;k++){
		if((ht[k].weight)<min1&&ht[k].parent==0){  //父节点值得判断起到筛选在集合中选过和没选过得值
			min1=ht[k].weight;
			falg1=k;
		}
	}
	for(int i=1;i<=len;i++)
	{
		if(ht[i].parent==0&&(ht[i].weight<min2)&&(i!=falg1))
		{
			min2=ht[i].weight;
			falg2=i;
	}
} //这里采用结构体的办法   更直观 
	check.falg1=falg1;
	check.falg2=falg2;
	return check;
}

1.23 建立哈夫曼树

//建立哈夫曼树
void CreateHuffmanTree(HuffmanTree &ht,int w[],int n)
{	MIN flag;
	int m=2*n-1;
	int i;
	//初始化
	for(i=1;i<=n;i++){
		ht[i]={w[i-1],0,0,0};
	} 
	for(i=n+1;i<=m;i++){
		ht[i]={0,0,0,0};
	}
	//从第n+1个元素开始创建
	for(i=n+1;i<=m;i++)
	{
		flag=select(ht,i-1);
		ht[i].weight=ht[flag.falg1].weight+ht[flag.falg2].weight;  //权值相加
		ht[i].lchild=flag.falg1;
		ht[i].rchild=flag.falg2;
		ht[flag.falg1].parent=i;
		ht[flag.falg2].parent=i;
	 } 
 } 

1.24 输出哈夫曼树

//输出哈夫曼树
 void show(HuffmanTree ht,int num){
 	for(int i=1;i<=num;i++)
 	{
 		printf("\n结点序号%d,权值为%d,父节点为 %d,左孩子结点为%d,右孩子结点为 %d",i,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
	}
 } 

?2.哈夫曼编码

首先得用到这个玩意:

#include<string.h>

2.1创建

//哈夫曼编码的实现
void Huffmanbianma(HuffmanTree ht,Huffmancode hc,int n)

//从叶子节点到根逆向求各叶子结点的编码 
{
	char *cd;
	int c,p;
	int start;
	cd=(char *)malloc(n*sizeof(char)); //临时编码数组
	cd[n-1]='\0';  //从后往前逐位求编码,最后一位是结束符先放
	for(int i=1;i<=n;i++)
	{
		start=n-1;  //因为是逆序,所以指针start从最后开始 
		c=i;        //当前结点,因为后面要进行指针的修改 
		p=ht[i].parent;  //取当前结点的父节点
		while(p!=0)
		{
			--start;
			if(ht[p].lchild==c)
			{
				cd[start]='0';  //左分支0  
			}else{
				cd[start]='1';   //右分支 1 
			}
			c=p; p=ht[p].parent;  //网上一层;	
		}
		hc[i]=(char *)malloc((n-start)*sizeof(char)); 
		strcpy(hc[i],&cd[start]);	
	}
	free(cd);	 
}

2.2 遍历

//遍历哈夫曼编码,也就是译码 
void TraverseCoding(Huffmancode HC, int n) {
	for (int i = 1; i <= n; ++i) {
		printf("哈夫曼编码:");
		puts(*(HC + i));
	}
}

因为没时间做讲解,代码过程都可以实现,所有创建过程我是直接定义数组,因为省事~~~~

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-24 15:33:08  更:2022-02-24 15:33:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:34:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码