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++实现

#include<iostream>
#include<iomanip>
using namespace std;
#pragma warning (disable: 4996)

类型定义

typedef struct {//哈夫曼树
	int weight;//权值
	int lch, rch, parent;//左右孩子,父结点
}HTNode,*HuffmanTree;

二级指针建立一个哈夫曼编码表

typedef char** HuffmanCode;
void CreatHuffmanTree(HuffmanTree& HT, int n) {
    //构造哈夫曼树
	if (n <= 1)return;
	int m = 2 * n - 1;//数组2n-1个元素
	HT = new HTNode[m + 1];//0号不用
	for (int i = 1; i <= m; i++) {
		//将2n-1个元素的lch,rch,parent设置为0
		HT[i].lch = 0; HT[i].rch = 0; HT[i].parent = 0;
	}
	for (int i = 1; i <= n; i++)
		cin >> HT[i].weight;//输入前n个元素的weight
	//初始化结束
	//建立哈夫曼树
	for (int i = n + 1; i <= m; i++) {
		//合并产生n-1个结点,构造哈夫曼树
		int s1, s2;
		Select(HT, i - 1, s1, s2);//找到i以前的最小的俩下标,用s1,s2返回
		HT[s1].parent = i;
		HT[s2].parent = i;
		//parent的初值为0,如果parent不为0,则说明已经构造成树了,可以用来Select函数判定
		HT[i].lch = s1;
		HT[i].rch = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}

}

Select函数是哈夫曼算法的重要过程,找到未成树的叶子结点的两个最小权值结点,并用s1,s2返回下标

void Select(HuffmanTree HT, int n, int& s1, int& s2) {
	s1 = s2 = 0;
	for (int i = 1; i <= n; i++) {
		if (HT[i].parent == 0) {
			s1 = i;
			break;
		}

	}//找一个未归树的结点开始判断

	for (int i = 1; i <= n; i++) {
		if (HT[i].parent == 0 && HT[i].weight < HT[s1].weight)
			s1 = i;
	}
	for (int i = 1; i <= n; i++) {
		if (HT[i].parent == 0 && i != s1) {//排除掉s1
			s2 = i;
			break;
		}
	}//找一个未归树的结点开始判断
	for (int i = 1; i <= n; i++) {
		if (HT[i].parent == 0 && HT[i].weight < HT[s2].weight && i != s1)//排除掉s1
			s2 = i;
	}
}

构造哈夫曼编码

从叶子一步一步向上回溯,找到自己的parent,然后得到自己是左还是右孩子

void CreateHuffmanCode(HuffmanTree&HT,HuffmanCode&HC,int n) {
	//从叶子到根逆向求每个字符的哈夫曼编码,储存在编码表HC中
	HC = new char* [n + 1];//分配n个字符编码的头指针矢量,第0个不放
	char* cd = new char[n];
	cd[n - 1] = '\0';
	for (int i = 1; i <= n; i++) {//i为初始为叶子,后面为当前回溯结
		int start = n - 1, c = i, f = HT[i].parent;
		while (f != 0) {
			--start;
			if (HT[f].lch == c)
				cd[start] = '0';//左0
			else cd[start] = '1';//右1
			c = f; f = HT[f].parent;
			//向上回溯一级
		}
		HC[i] = new char[n - start];//分配该编码所需要的空间
		strcpy(HC[i], &cd[start]);//从start开始复制
	}
	delete cd;
}

打印哈夫曼树表,setw是#include<iomanip>里面的,用来方便输出

void PrintHuffman(HuffmanTree HT, int n) {
	cout << "index weight parents lchild rchild" << endl;
	cout << left;
	for (int i = 1; i <= 2 * n - 1; i++) {
		cout << setw(6) << i << " ";
		cout << setw(6) << HT[i].weight << " ";
		cout << setw(6) << HT[i].parent << " ";
		cout << setw(6) << HT[i].lch << " ";
		cout << setw(6) << HT[i].rch << " " << endl;
	}
}

打印编码表

void PrintHuffmancode(HuffmanCode&HC,int n) {
	cout << "每个叶子的哈夫曼编码为" << endl;
	for (int i = 1; i <= n; i++) {
		cout << HC[i] << endl;
	}
}

测试函数test01

void test01() {
	HuffmanTree HT;
	HuffmanCode HC;
	int n=0;
	cin >> n;

	CreatHuffmanTree(HT, n);
	PrintHuffman(HT, n);
	CreateHuffmanCode(HT, HC, n);
	PrintHuffmancode(HC, n);

	//7 40 30 15 5 4 3 3

}

?结果

?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-23 12:37:09  更:2021-11-23 12:38:57 
 
开发: 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 16:01:34-

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