数据结构之哈夫曼编码,哈夫曼树

哈夫曼编码原理请自行百度,仅贴上本咸鱼的代码与运行截图

//By Sean Chen
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <cstdlib>
using namespace std;

class treenode{
public:
	char data;
	int num;
	treenode *leftson,*rightson;
	treenode()
	{
		leftson=NULL;
		rightson=NULL;
	}
};

struct cmp{
	bool operator () (treenode *a,treenode *b)
	{
		return a->num>b->num;
	}
};

treenode *root;
map <char,string> Map;       //用map存储字符对应的编码
char temp[500];                //用于存储目前遍历树时的编码
char code[10005];
char ans[100005];
priority_queue <treenode*,vector<treenode*>,cmp> Q;     //优先队列,建树时有用

//建立霍夫曼树
void Buildtree()
{
	int n;
	printf("Input the total number of the characters:\n>");
	scanf("%d",&n);
	for (int i=1;i<=n;i++)             //读入节点
	{
		treenode *tempnode=new treenode;
		getchar();
		printf("Input the %dth character and its frequency:\n>",i);
		scanf("%c%d",&tempnode->data,&tempnode->num);
		Q.push(tempnode);
	}
	while (Q.size()>1)         //利用优先队列建树
    {
        treenode *a,*b,*c=new treenode;
        a=Q.top();             //取优先队列头两个元素
        Q.pop();
        b=Q.top();
        Q.pop();
        /*cout<<a->data<<endl<<b->data<<endl;
        system("pause");*/
        c->leftson=a;                //建立新节点
        c->rightson=b;
        c->num=a->num+b->num;
        c->data='\0';
        Q.push(c);                 //结点的权为左右子节点权值之和,并压入优先队列
    }
    root=Q.top();
    Q.pop();
    return;
}

void dfs(treenode *pos)         //深搜进行编码
{
    if (pos->data!='\0')       //找到叶子结点
    {
        Map[pos->data]=temp;    //编码
        return;
    }
    if (pos->leftson!=NULL)     //左子树
    {
        temp[strlen(temp)]='0';
        dfs(pos->leftson);
        temp[strlen(temp)-1]='\0';
    }
    if (pos->rightson!=NULL)   //右子树
    {
        temp[strlen(temp)]='1';
        dfs(pos->rightson);
        temp[strlen(temp)-1]='\0';
    }
    return;
}

//编码
void Encode()           //对字符进行编码并输出
{
    memset(temp,'\0',sizeof(temp));
    dfs(root);
    map<char,string>::iterator iter;
    for (iter=Map.begin();iter!=Map.end();iter++)
    {
        printf("The code of %c is: ",iter->first);
        cout<<iter->second<<endl;
    }
    return;
}

//输出某一字符串的霍夫曼编码
void ShowCode()
{
    gets(code);
    printf("The Huffman-Code of %s is:\n",code);
    for (int i=0;i<strlen(code);i++)        //逐个字符输出
        cout<<Map[code[i]];
    cout<<endl;
    return;
}

//将某个霍夫曼编码转为字符串,若霍夫曼编码有问题,则报错
void Decode()
{
    treenode *temppos=root;
    gets(code);
    printf("The String of Huffman-Code %s is:\n",code);
    for (int i=0;i<strlen(code);i++)
    {
        if (code[i]=='0' && temppos->leftson!=NULL)      //编码值为‘0’,左子树
            temppos=temppos->leftson;
        else if (code[i]=='1' && temppos->rightson!=NULL)     //右子树
            temppos=temppos->rightson;
        else                     //报错
        {
            printf("The Huffman-Code is Wrong!\n");
            break;
        }
        if (temppos->data!='\0')            //找到一个节点
        {
            printf("%c",temppos->data);
            temppos=root;
        }
    }
    cout<<endl;
    return;
}

int main()
{
    Buildtree();
    int flag=1;
    int oper;
    while (flag)
    {
        system("cls");
        memset(ans,'\0',sizeof(ans));
        memset(code,'\0',sizeof(code));
        Encode();
        printf("choose your operation:\n1:Encode a String\n2:Decode a String\n3:End\n>");
        scanf("%d",&oper);
        getchar();
        switch (oper)
        {
            case 1:
            {
                ShowCode();
                system("pause");
                break;
            }
            case 2:
            {
                Decode();
                system("pause");
                break;
            }
            case 3:
            {
                flag=0;
                break;
            }
            default:
            {
                printf("Wrong Input,Please Input again!");
                system("pause");
                break;
            }
        }
    }
    return 0;
}

附上两张运行截图,分别为编码和解码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值