最近拖更了好久,在忙一些琐事,有时间继续加更!
上次实验三二叉树递归与非递归版本已经全部公开,请点击此处。
数据结构实验四要求
题目描述:对任意输入的一段英文,为每个字符编制其相应的哈夫曼编码,并利用该编码为任意输入的0、1序列进行解码。
操作提示:一个完整的系统应具有以下功能:
(1)初始化:从终端读入一段英文字符,统计每个字符出现的频率,建立哈夫曼树,并将该树存入某文件;
(2)编码: 利用建好的哈夫曼树对各字符进行编码,用列表的形式显示在屏幕上,并将编码结果存入另一文件中;
(3)解码: 利用保存的哈夫曼编码,对任意输入的0,1序列能正确解码。
话说我用C语言写的,有好多指针还是挺绕的,虽然思路对的但得不出正确答案,索性使用引用,对指针掌握还是有所欠缺,以后还是好好用C++吧(捂脸ing)。
这次方便同学提供部分主要函数代码(后天代码全部公开)见下:
Tree.h
#ifndef _TREE_H_
#define _TREE_H_
#include <iostream>
#include <string>
#include <cstring>
#include <map>
#include <fstream>
using namespace std;
map<char,int> str;//全局变量,键值对,对字符计数
const int INFMAX=0x3f3f3f3f;
typedef struct{
char c;
int parent;
int LChild;
int RChild;
int weight;
}HTNode,*huffman;
typedef char ** huffmancode;
#endif
Tree.cpp
#include "Tree.h"
/*从ht树中,范围是1-n,选出最小的2个赋值给s1,s2*/
void Select(huffman ht,int n,int &s1,int &s2){
int min=INFMAX;
for(int i=1;i<=n;i++){
if(ht[i].parent==0&&ht[i].weight<min){
min=ht[i].weight;
s1=i;
}
}
min=INFMAX;
for(int i=1;i<=n;i++){
if(ht[i].parent==0&&ht[i].weight<min&&i!=s1){
min=ht[i].weight;
s2=i;
}
}
}
/*创建huffmantree,注意使用&*/
void CreatHuffmanTree(huffman &ht,int n){
int m=2*n-1;
ht=new HTNode[m+1];//第0号位置不使用
map<char,int>::iterator it=str.begin();
//初始化n个结点的信息
for(int i=1;i<=n&&it!=str.end();++i,++it){
ht[i].c=it->first;
ht[i].parent=0;
ht[i].LChild=0;
ht[i].RChild=0;
ht[i].weight=it->second;
}
for(int i=n+1;i<=m;i++){
ht[i].parent=0;
ht[i].LChild=0;
ht[i].RChild=0;
ht[i].weight=0;
}
for(int i=n+1;i<=m;i++){
int s1,s2;
Select(ht,i-1,s1,s2);
ht[s1].parent=i;ht[s2].parent=i;
ht[i].LChild=s1;ht[i].RChild=s2;
ht[i].weight=ht[s1].weight+ht[s2].weight;
}
}
/*通过huffman树进行解码,左为0,右为1*/
void CreatHuffmanCode(huffman ht,int n,huffmancode &hc){
int m=2*n-1;
hc=new char*[n+1];
char *cd;
cd=new char[n+1];
cd[n-1]='\0';
for(int i=1;i<=n;++i){
int start=n-1;
int c=i;
int f=ht[i].parent;
while(f!=0){
--start;
if(ht[f].LChild==c){
cd[start]='0';
}
else{
cd[start]='1';
}
c=f;
f=ht[f].parent;
}
hc[i]=new char[n-start];
strcpy(hc[i],&cd[start]);
}
delete cd;
}
void Decode(huffman ht,int n,string str){
HTNode p=ht[2*n-1];
for(int i=0;i<str.length();++i){
if(str[i]=='0'){
p=ht[p.LChild];
}else if(str[i]=='1'){
p=ht[p.RChild];
}
if(p.LChild==0&&p.RChild==0){
cout<<p.c;
p=ht[2*n-1];
}
}
}