赞
踩
- 说明:这是武汉理工大学计算机学院【算法设计与分析】课程的第二次实验第一题:哈夫曼编码问题
- >>点击查看武汉理工大学计算机专业课程资料汇总
- >>点击查看WUTer计算机专业实验汇总
- 谨记:纸上得来终觉浅,绝知此事要躬行。
设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。
(1)证明哈夫曼树满足最优子结构性质;
(2)设计贪心算法求解哈夫曼编码方案;
(3)设计测试数据,写出程序文档。
- #include <iostream>
- using namespace std;
- #define MAXCODELEN 100 //最大字符编码数组长度
- #define MAXHAFF 100 //最大哈夫曼节点结构体数组个数
- #define MAXCODE 100 //最大哈夫曼编码结构体数组的个数
- #define MAXWEIGHT 10000; //最大字符编码权值
- typedef struct Huffman{
- int weight; //权重
- char ch; //字符
- int parent; //父节点
- int leftChild; //左儿子节点
- int rightChild; //右儿子节点
- }HuffmanNode;
- typedef struct Code{
- int code[MAXCODELEN]; //字符的哈夫曼编码的存储
- int start; //从哪个位置开始
- }HuffmanCode;
- HuffmanNode huffman[MAXHAFF];
- HuffmanCode code[MAXCODE];
- void createHuffman(int all){
- //初始化Huffman树
- for (int i = 0; i < all * 2 - 1; ++i){
- huffman[i].weight = 0;
- huffman[i].parent = -1;
- huffman[i].leftChild = -1;
- huffman[i].rightChild = -1;
- }
- /*提示用户输入数据*/
- cout << "请依次输入" << all << "个需要哈夫曼编码的字符:";
- for (int i = 0; i < all;i++) {
- cin >> huffman[i].ch;
- }
- cout << "请依次输入"<<all<<"个字符对应的的权值:";
- for (int i = 0; i < all; i++) {
- cin >> huffman[i].weight;
- }
- //每次循环找出权值最小的两个节点,生成新的父亲节点。共需要 all - 1 次合并
- int x1, x2, w1, w2; //w1、w2分别为最小的两个节点
- for (int i = 0; i < all - 1; ++i){
- x1 = x2 = -1;
- w1 = w2 = MAXWEIGHT; //初始化最小节点权值
- for (int j = 0; j < all + i; ++j){
- if (huffman[j].parent == -1 && huffman[j].weight < w1){ //找到无父节点并且权值最小
- w2 = w1;
- x2 = x1;
- x1 = j;
- w1 = huffman[j].weight;
- }
- else if (huffman[j].parent == -1 && huffman[j].weight < w2){ //找到第二小的无父亲节点
- x2 = j;
- w2 = huffman[j].weight;
- }
- }
- //将上面找到的最小权值节点合并成一个新的父亲节点
- huffman[all + i].leftChild = x1;
- huffman[all + i].rightChild = x2;
- huffman[all + i].weight = w1 + w2;
- huffman[x1].parent = all + i;
- huffman[x2].parent = all + i;
- }
- }
- //打印每个字符的哈夫曼编码
- void printCode(int all){
- HuffmanCode hCode;//保存当前叶子节点的字符编码
- int curParent; //当前父节点
- int c; //下标和叶子节点的编号
- for (int i = 0; i < all; ++i) {
- hCode.start = all - 1;
- c = i;
- curParent = huffman[i].parent;
- while (curParent != -1) {
- if (huffman[curParent].leftChild == c){ hCode.code[hCode.start] = 0; }
- else{ hCode.code[hCode.start] = 1; }
- hCode.start--;
- c = curParent;
- curParent = huffman[c].parent;
- }
- //把当前的叶子节点信息保存到编码结构体里面
- for (int j = hCode.start + 1; j < all; ++j){
- code[i].code[j] = hCode.code[j];
- }
- code[i].start = hCode.start;
- }
- cout << endl;
- for (int i = 0; i < all; ++i) {
- cout << huffman[i].ch << " 字符的哈夫曼编码是:";
- for (int j = code[i].start + 1; j < all; ++j) {
- cout << code[i].code[j];
- }
- cout << endl;
- }
- }
- int main(){
- int all = 0;
- cout << "请输入哈夫曼字符个数:"; cin >> all;
- if (all <= 0){
- cout << "您输入的个数有误" << endl;
- return -1;
- }
- createHuffman(all);
- printCode(all);
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。