[解析]ハフマンアルゴリズムの設計とコーディングの問題

免責事項:この記事はブロガーオリジナル記事です。再現ブロガーの承認を連絡してください。ブロガー公共マイクロチャネル番号] [部門知るのとキャンパスを行います。https://blog.csdn.net/cxh_1231/article/details/89715953
  • 説明:ハフマン符号化問題:これは、[コース]アルゴリズム設計と最初の質問コンピュータ科学、技術の武漢大学の第二の試験の分析があります
  • >>要約WUTer実験的なコンピュータサイエンスはこちら
  • 注意:紙はこの練習が不可欠である知っているZhongjue来ます。

まず、実験対象:

     符号化された文字を設定するように設けられ、{ D 1 D 2 、...、D N- } 、それらの出現頻度{ W 1 W 2 、...、W N - } 、アプリケーション最短ハフマンツリー構造可変長符号プログラム。

第二に、実験的な要件:

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;
}

第四に、実験結果:

おすすめ

転載: blog.csdn.net/cxh_1231/article/details/89715953
おすすめ