记录数据结构pta作业——哈夫曼编码
题目
本题要求字符的哈夫曼编码,注意建立的哈夫曼树严格按照左小右次小的顺序,并且哈夫曼编码时严格按照左‘0’右‘1’进行编码。
输入格式:
输入是各个字符在通信中出现的频率
输出格式:
输出是各个字符的哈夫曼编码,每个字母占一行
输入样例:
A:2
B:3
C:6
D:7
E:10
F:19
G:21
H:32
输出样例:
A:10000
B:10001
C:1001
D:1010
E:1011
F:00
G:01
H:11
思路
- 结点有左右孩子和双亲
- 用栈和队列记录输入的数据和权重,并记录个数n
- 顺序存储2n-1个结点(哈夫曼树的总节点数)
- 每次寻找权值最小两个结点,并构造一个新结点,该两个结点标记为找过,最终构建成哈夫曼树
- 左孩子标记为0,右孩子标记为1,利用栈,输出该n个结点的哈夫曼编码
代码
#include<iostream>
#include<array>
#include<queue>
#include<stack>
using namespace std;
typedef struct node{
int data;
char ch;
int lchild,rchild,parent;
}Node,*pNode;
void select(pNode &nodes,int &min1,int &min2,int size){//找最小两个
for(int i = 0;i < size;i++){
if(nodes[i].parent == -1){
if(min1 == -1){
min1 = i;
}
else if(min2 == -1){
min2 = i;
}
else{
if(nodes[min1].data > nodes[min2].data){
if(nodes[min1].data > nodes[i].data){
min1 = i;
}
}
else{
if(nodes[min2].data > nodes[i].data){
min2 = i;
}
}
}
}
}
}
int main(){
char ch;
char maohao;
int weight;
int n = 0;
queue<char> chs;
queue<int> weights;
while( cin >> ch){//记录所有数据
cin >> maohao;
cin >> weight;
chs.push(ch);
weights.push(weight);
n++;
}
pNode nodes = new Node[2*n-1];
for(int i = 0; i < n; i++){//构造叶子结点
nodes[i].data = weights.front();
nodes[i].ch = chs.front();
nodes[i].lchild = nodes[i].rchild = nodes[i].parent = -1;
weights.pop();
chs.pop();
}
for(int i = n;i<2*n-1;i++){//构造哈夫曼树
int min1 = -1;
int min2 = -1;
select(nodes,min1,min2,i);
if(nodes[min1].data > nodes[min2].data){
int temp = min1;
min1 = min2;
min2 = temp;
}
nodes[i].data = nodes[min1].data + nodes[min2].data;
nodes[i].lchild = min1;
nodes[i].rchild = min2;
nodes[i].parent = -1;
nodes[min1].parent = i;
nodes[min2].parent = i;
}
for(int i = 0;i < n;i++){//利用栈输出哈夫曼编码
stack <int> code;
cout << nodes[i].ch << ":";
int par = nodes[i].parent;
int child = i;
while(par != -1){
if(nodes[par].lchild == child){
code.push(0);
}
else if(nodes[par].rchild == child){
code.push(1);
}
par = nodes[par].parent;
child = nodes[child].parent;
}
while(!code.empty()){
cout << code.top();
code.pop();
}
cout<<endl;
}
system("pause");
return 0;
}