pta——哈夫曼编码

记录数据结构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

思路

  1. 结点有左右孩子和双亲
  2. 用栈和队列记录输入的数据和权重,并记录个数n
  3. 顺序存储2n-1个结点(哈夫曼树的总节点数)
  4. 每次寻找权值最小两个结点,并构造一个新结点,该两个结点标记为找过,最终构建成哈夫曼树
  5. 左孩子标记为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;
}


  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值