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语言)哈夫曼树 11月25日 -> 正文阅读

[数据结构与算法]数据结构(C语言)哈夫曼树 11月25日

实验内容:

1.设置7个字符a~g的权值,以它们为叶子构造哈夫曼树

2. 输出它们的哈夫曼编码。

哈夫曼树:

#include<stdio.h>
#include<stdlib.h>
#include"string.h"
//哈夫曼树
#define MAXLEAF 100  //最多叶子节点数
#define MAXVALUE 100  //最大权值

typedef struct {
	int weight;//权值
	int parent;//父节点
	int lchild;//左孩子
	int rchild;//右孩子
}hnodetype;


int n = 7;//叶子节点个数,全局变量
//哈夫曼算法生成哈夫曼树(最优二叉树)
void huffmantree(hnodetype huffnode[MAXLEAF], int n) {
	int i = 0, j = 0;
	for (i = 0; i < 2 * n - 1; i++) //初始化huffnode数组
	{
		huffnode[i].weight = 0;  huffnode[i].parent = -1;
		huffnode[i].lchild = -1; huffnode[i].rchild = -1;
	}
	for (i = 0; i < n; i++)
		scanf_s("%d", &huffnode[i].weight);
	
	
	//找最小值与次小值
	for (i = 0; i < n - 1; i++) //找最小值m1和次小值m2循环 n - 1轮,如5个叶子节点要循环4次,所以是n-1
	{
		int m1, m2, x1, x2;

		m1 = m2 = MAXVALUE;//权值
		x1 = x2 = -1;//权值所在的下标
		//寻找最小值m1和次小值m2
		for (j = 0; j < n + i; j++) {
			if (huffnode[j].weight < m1 && huffnode[j].parent == -1) //当前值是j,和m1相比
				//加huffnode[j].parent == -1这个条件是为了排除已经有父节点的结点,即已经合并过的结点
				//进行合并的时候要选那些没有父节点的结点
			{
				m2 = m1;
				x2 = x1;
				m1 = huffnode[j].weight;
				x1 = j;
			}//如果j<m1,则m1变成当前值j,同时m2变成m1,x1变成j,x2变成x1
			else if (huffnode[j].weight < m2 && huffnode[j].parent == -1)
			{
				m2 = huffnode[j].weight;
				x2 = j;
			}//与m2相比,就把m2赋值为当前值j即可
		}
		//选中x1,x2进行合并
		huffnode[n + i].weight = m1 + m2;//合并后新节点的下标是n+i,i代表当前第几轮,第一轮i=0,新节点的权值为m1 + m2
		huffnode[n + i].lchild = x1; huffnode[n + i].rchild = x2;//对左右孩子进行赋值
		huffnode[x1].parent = n + i; huffnode[x2].parent = n + i;//修正下标x1和x2对应的父节点为新节点
	}
}

//输出所有节点的权值
void output(hnodetype huffnode[MAXLEAF], int n) {
	int i = 0;
	for (i = 0; i < 2 * n - 1; i++) {
		printf("%d\t", huffnode[i].weight);
	}
	printf("\n");
}
//求哈夫曼编码:递归做法
void getcode1(hnodetype huffnode[MAXLEAF], int i, char dest[], int len) 
//i是根节点的下标,dest[]是编码保存的地方,保存在一个字符串数组,len是长度
{
	if (huffnode[i].lchild == -1 && huffnode[i].rchild == -1) {
		dest[len] = 0;//字符串结束字符
		printf("%-6c%-8d%-10s\n", i + 97, huffnode[i].weight, dest);
		return;
	}
	if (huffnode[i].lchild != -1) {
		dest[len] = '0';
		getcode1(huffnode, huffnode[i].lchild, dest, len + 1);//()里是参数情况
	}//判断左孩子,并对做递归调用
	if (huffnode[i].rchild != -1) {
		dest[len] = '1';
		getcode1(huffnode, huffnode[i].rchild, dest, len + 1);
	}
}

//求哈夫曼编码:循环
void getcode2(hnodetype huffnode[MAXLEAF], int n) {
	int i = 0;
	for (i = 0; i < n; i++) {
		int c = i;//第i个,第一个时c=i,i=1
		int f = 0;//父节点下标
		int j = 0;
		int code[MAXLEAF] = { 0 };//编码数组,记录编码
		int len = 0;
		f = huffnode[c].parent;
		while (f >= 0) {//父节点不为-1的时候
			//printf("%d,%d\n", huffnode[f].weight, huffnode[f].lchild);
			if (huffnode[f].lchild == c)
				code[len++] = 0;
			else
				code[len++] = 1;//记录一下是左孩子还是右孩子
			c = f;//把当前结点变成f
			f = huffnode[c].parent;//f记成f的下一个
		}
		//反向输出数组,即编码
		printf("%-6c%-8d", i + 97, huffnode[i].weight);
		for (j = len - 1; j >= 0; j--)
			printf("%d", code[j]);
		printf("\n");
	}
}

int main(void)
{
	int n = 7;
	printf("输入a~g的权值:");
	hnodetype huffnode[MAXLEAF];
	huffmantree(huffnode, n);
	printf("所有节点权值:");
	output(huffnode, n);
	char dest[MAXLEAF] = "";
	printf("\n递归方法:\n");
	printf("%-6s%-8s%-10s\n", "字符", "权值", "编码");
	getcode1(huffnode, 2 * n - 2, dest, 0);
	printf("\n循环方法:\n");
	printf("%-6s%-8s%-10s\n", "字符", "权值", "编码");
	getcode2(huffnode, n);
	printf("\n");
	return 0;
}

运行结果:

?

?

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

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 15:39:25-

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