神秘电报密码——哈夫曼编码

C++源码:

#include<algorithm>
#include<iostream>
#include<conio.h>
#include<cstring>
#include<cstdlib>
using namespace std;
#define MAXBIT 100
#define MAXVALUE 10000
#define MAXLEAF 30
#define MAXNODE MAXLEAF*2-1
typedef struct
{
	double weight;
	int parent;
	int lchild;
	int rchild;
	char value;
}HNodeType;//结点结构体
typedef struct
{
	int bit[MAXBIT];
	int start;
}HCodeType;//编码结构体
HNodeType HuffNode[MAXNODE];//定义一个结构体数组
HCodeType HuffCode[MAXLEAF];//定义一个编码结构体数组
//构造哈夫曼树
void HuffmanTree(HNodeType HuffNode[MAXNODE],int n){
	//i、j循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,x1、x2:构造哈夫曼树不同过程中两个权值结点在数组中的序号
	int i,j,x1,x2;
	double m1,m2;
	//初始化存放哈夫曼树数组HuffNode[]中的节点,哈夫曼树有2n-1个结点(n-1+n)
	for(i=0;i<2*n-1;i++)
	{
		HuffNode[i].weight=0;
		HuffNode[i].parent=-1;
		HuffNode[i].rchild=-1;
		HuffNode[i].lchild=-1;
	}
	//输入n个叶子结点的权值
	for(i=0;i<n;i++)
	{
		cout<<"Please input value and weight of leaf node:"<<i+1<<endl;
		cin>>HuffNode[i].value>>HuffNode[i].weight;
	}
		//构造哈夫曼树
	for(i=0;i<n-1;i++){
		//执行n-1次合并
		m1=m2=MAXVALUE;//m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值
		x1=x2=0;//找出所有节点中权值最小、无父结点的两个节点,并合之为一棵二叉树
		for(j=0;j<n+i;j++)
		{
			if(HuffNode[j].weight<m1 && HuffNode[j].parent==-1)
			{
				m2=m1;
				x2=x1;
				m1=HuffNode[j].weight;
				x1=j;
			}
			else if(HuffNode[j].weight<m2 && HuffNode[j].parent==-1)
			{
				m2=HuffNode[j].weight;
				x2=j;
			}
		}
		HuffNode[x1].parent=n+i;
		HuffNode[x2].parent=n+i;
		HuffNode[n+i].weight=m1+m2;
		HuffNode[n+i].lchild=x1;
		HuffNode[n+i].rchild=x2;
		cout<<"x1.weight and x2.weight in round  "<<i+1<<"\t"<<HuffNode[x1].weight<<"\t"<<HuffNode[x2].weight<<endl;//用于测试
	}
}
//哈夫曼编码
void HuffmanCode(HCodeType HuffCode[MAXLEAF],int n){
	HCodeType cd;//定义一个临时变量来存放求解编码时的信息
	int i,j,c,p;
	for(i=0;i<n;i++)
	{
		cd.start=n-1;
		c=i;//存放结点
		p=HuffNode[c].parent;
		while(p!=-1)
		{
			if(HuffNode[p].lchild==c)
				cd.bit[cd.start]=0;
			else
				cd.bit[cd.start]=1;
			cd.start--;//求编码的低一位
			c=p;
			p=HuffNode[c].parent;//设置下一循环条件
		}
		//把叶子结点的编码信息从临时编码cd中复制出来,放置到编码结构体数组HuffCode[i]
		for(j=cd.start+1;j<n;j++)
			HuffCode[i].bit[j]=cd.bit[j];
		HuffCode[i].start=cd.start;
	}
}
int main(){
	int i,j,n;
	cout<<"Please input n : "<<endl;
	cin>>n;
	HuffmanTree(HuffNode,n);//构造哈夫曼树
	HuffmanCode(HuffCode,n);//哈夫曼树编码
	//输出已保存好的所有存在编码的哈夫曼编码
	for(i=0;i<n;i++)
	{
		cout<<HuffNode[i].value<<":Huffman code is: ";
		for(j=HuffCode[i].start+1;j<n;j++)
		{
			cout<<HuffCode[i].bit[j];
		}
		cout<<endl;
	}
	getch();
	return 0;
}

运行结果:

 python源码:

MAXBIT=100
MAXVALUE=10000
MAXLEAF=30
MAXNODE=MAXLEAF*2-1
n=int(input("请输入共有多少个字符:n="))
weight=[0.0]*(2*n-1)
parent=[-1]*(2*n-1)
lchild=[-1]*(2*n-1)
rchild=[-1]*(2*n-1)
value=[""]*(2*n-1)
print(value)
bit=[1]*n
#start=[i for i in range(n)]
num=1
HCodeType=[[bit,num] for i in range(MAXLEAF)]
print(HCodeType)
for i in range(n):
    print("Please input the value and weight of leaf node: ",i+1)
    value[i]=str(input("value:"))
    weight[i]=float(input("weight:"))
HNodeType=[[weight[i],parent[i],lchild[i],rchild[i],value[i]] for i in range(2*n-1)]
print((HNodeType))
def HuffmanTree(HNodeType,n):
    #i、j循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,x1、x2:构造哈夫曼树不同过程中两个权值结点在数组中的序号
    for i in range(n-1):#n-1次组合
        m1=m2=MAXVALUE#初始化为最大值
        x1=-1
        x2=-1
        #找出所有节点中,权值最小、无双亲结点的两个结点
        for j in range(n+i):
            if HNodeType[j][0]<m1 and HNodeType[j][1]==-1 :
                m2=m1
                x2=x1
                m1=HNodeType[j][0]
                x1=j
            elif HNodeType[j][0]<m2 and HNodeType[j][1]==-1:#用以处理两个结点权值相同的情况(利用m1=m2的特性)
                m2=HNodeType[j][0]
                x2=j
        HNodeType[x1][1]=n+i#x1的父亲(前驱节点)为新结点编号n+i
        HNodeType[x2][1]=n+i#x2的父亲为新结点编号n+i
        HNodeType[n+i][0]=m1+m2
        HNodeType[n+i][2]=x1
        HNodeType[n+i][3]=x2
#输出哈夫曼编码

def HuffmanCode(HCodeType,n):
    for i in range(n):
        start = n - 1
        c=i
        p=HNodeType[c][1]
        while p!=-1 :
            if HNodeType[p][2]==c :
                bit[start]=0
            else:bit[start]=1
            start-=1
            c=p
            p=HNodeType[c][1]
        for j in range(start+1,n):
            HCodeType[i][0][j]=bit[j]
        HCodeType[i][1]=start
HuffmanTree(HNodeType,n)
HuffmanCode(HCodeType,n)
for i in range(n):
    print(HNodeType[i][4],": Huffman code is : ",end="")
    for j in range(HCodeType[i][1]+1,n):
        print(HCodeType[i][0][j],end="")
    print(" ")

运行结果:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古剑诛仙

你的鼓励是我创造的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值