大二(上) 数据结构 哈夫曼编码


#include<iostream>
#define MAX 200
using namespace std;
typedef char ElementType;
typedef double wghType;

typedef struct {
	ElementType Data;
	int w;
	int parent, lchild, rchild;
}HFMTNode;

//每个节点的编码
//code存储编码
//start存储编码是从code数组的第几个开始
//在编码过程中从叶子节点向根节点逆推
struct HFMTcode
{
	char code[MAX];
	int start;
};
//建立哈夫曼树
void CreateHFMTree(HFMTNode Ht[], int N)
{
	int i, k, lmin, rmin;
	int min1, min2;
	for (i = 1; i < 2 * N; i++)
	{
		min1 = min2 = MAX;
		lmin = rmin = -1;
		for (k = 1; k <= i - 1; k++)
			if (Ht[k].w == -1)
			{
				if (Ht[k].w < min1) {
					min2 = min1;
					rmin = lmin;
					min1 = Ht[k].w;
					rmin = k;
				}
				else if (Ht[k].w < min2)
				{
					min2 = Ht[k].w;
					rmin = k;
				}
			}
		Ht[lmin].parent = i;
		Ht[rmin].parent = i;
		Ht[i].w = Ht[lmin].w + Ht[rmin].w;
		Ht[i].lchild = lmin;
		Ht[i].rchild = rmin;
	}
}
//求每个节点的哈夫曼编码
void createHFMcode(HFMTNode *node, HFMTcode *hcode, int n)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		HFMTcode d;
		//哈夫曼树最大层数就是元素的个数
		d.start = n;
		int num = i;
		int father = node[num].parent;
		while (father != 0)
		{
			if (node[father].lchild == num)
				d.code[d.start--] = '0';
			else
				d.code[d.start--] = '1';
			num = father;
			father = node[num].parent;
		}
		hcode[i] = d;
	}
}
//打印每个节点的编码
void printHFMcode(HFMTNode * node, HFMTcode * hcode, int n)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		cout << node[i].Data << " :";
		for (int k = hcode[i].start + 1; k <= n; k++)
			cout << hcode[i].code[k];
		cout << endl;
	}
}


int  main(int argc, char* argv[])
{
	HFMTNode node[2 * MAX];
	HFMTcode hcd[MAX];

	cout << "请输入元素个数:" << endl;
	int n;
	cin >> n;
	int i;
	for (i = 1; i <= n; i++)
	{
		cout << "输入第" << i << "个节点的值:" << endl;
		cin >> node[i].Data;
		cout << "输入它的权重:" << endl;
		cin >> node[i].w;
	}
	for (i = 1; i <= 2 * n - 1; i++)
	{
		node[i].parent = node[i].lchild = node[i].rchild = 0;
	}
	//建立哈夫曼树
	CreateHFMTree(node, n);
	//求每个节点的哈夫曼编码
	createHFMcode(node, hcd, n);
	//打印每个节点的编码
	cout << "输出每个节点的哈夫曼编码:" << endl;
	printHFMcode(node, hcd, n);
	
	cout << "请输入译码:" << endl;
	DeCoding(node, n);

	system("pause");
	return 0;
}
#include<iostream>
#include<stdio.h>
#define MAX 20
#define maxsize 100
using namespace std;
typedef char ElementType;

struct HFMnode
{
	ElementType data;
	int weight;
	int parent, lchild, rchild;
};

//每个节点的编码
//code存储编码
//start存储编码是从code数组的第几个开始
//在编码过程中从叶子节点向根节点逆推
struct HFMcode
{
	char code[MAX];
	int start;
};

//建立哈夫曼树
void createHFMtree(HFMnode *node, int n)
{
	int i;
	//m1,m2为当前还没用到的节点中权值最小和次小的权值
	int m1, m2;
	//l,r为每次构建一个父节点其左右儿子节点的序号
	int l, r;
	for (i = n + 1; i <= 2 * n - 1; i++)
	{
		m1 = m2 = 32767;
		l = r = 0;
		int k;
		for (k = 1; k <= i - 1; k++)
			if (node[k].parent == 0)
			{
				if (node[k].weight < m1)
				{
					m2 = m1;
					r = l;
					m1 = node[k].weight;
					l = k;
				}
				else if (node[k].weight < m2)
				{
					m2 = node[k].weight;
					r = k;
				}
			}
		node[i].weight = node[l].weight + node[r].weight;
		node[i].lchild = l;
		node[i].rchild = r;
		node[l].parent = i;
		node[r].parent = i;
	}
}

//求每个节点的哈夫曼编码
void createHFMcode(HFMnode *node, HFMcode *hcode, int n)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		HFMcode d;
		//哈夫曼树最大层数就是元素的个数
		d.start = n;
		int num = i;
		int father = node[num].parent;
		while (father != 0)
		{
			if (node[father].lchild == num)
				d.code[d.start--] = '0';
			else
				d.code[d.start--] = '1';
			num = father;
			father = node[num].parent;
		}
		hcode[i] = d;
	}
}

void HuffmanTranslateCoding(HFMnode* HT, int n, char* ch)
{
	//译码过程
	int m = 2 * n - 1;
	int i, j = 0;

	printf("After Translation:");
	while (ch[j] != '\0')                 //ch[]:你输入的要译码的0101010串
	{
		i = m;
		while (0 != HT[i].lchild && 0 != HT[i].rchild)   //从顶部找到最下面
		{
			if ('0' == ch[j])                //0 往左子树走
			{
				i = HT[i].lchild;
			}
			else                              //1 往右子树走
			{
				i = HT[i].rchild;
			}
			++j;                             //下一个路径
		}
		printf("%c", HT[i - 1].data);                  //打印出来
	}
	printf("\n");
}



//打印每个节点的编码
void printHFMcode(HFMnode * node, HFMcode * hcode, int n)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		cout << node[i].data << " :";
		for (int k = hcode[i].start + 1; k <= n; k++)
			cout << hcode[i].code[k];
		cout << endl;
	}
}

int main(int argc, char* argv[])
{
	HFMnode node[2 * MAX];
	HFMcode hcd[MAX];
	
	cout << "请输入元素个数:" << endl;
	int n;
	cin >> n;
	int i;
	for (i = 1; i <= n; i++)
	{
		cout << "输入第" << i << "个节点的值:" << endl;
		cin >> node[i].data;
		cout << "输入它的权重:" << endl;
		cin >> node[i].weight;	
	}
	for (i = 1; i <= 2 * n - 1; i++)
	{
		node[i].parent = node[i].lchild = node[i].rchild = 0;
	}
	//建立哈夫曼树
	createHFMtree(node, n);
	//求每个节点的哈夫曼编码
	createHFMcode(node, hcd, n);
	//打印每个节点的编码
	cout << "输出每个节点的哈夫曼编码:" << endl;
	printHFMcode(node, hcd, n);

	cout << "哈夫曼译码:" << endl;
	char tran[100];
	gets_s(tran,10);
	HuffmanTranslateCoding(node, n, tran);

	system("pause");
	return 0;
}

正确版本

#include<iostream>
#include<stdio.h>
#define MAX 500
#define maxsize 1000
using namespace std;
typedef char ElementType;

struct HFMnode
{
	ElementType Data;
	int w;
	int parent, lchild, rchild;
};

//每个节点的编码
//code存储编码
//start存储编码是从code数组的第几个开始
//在编码过程中从叶子节点向根节点逆推
struct HFMcode
{
	char code[MAX];
	int start;
};

//建立哈夫曼树
void createHFMtree(HFMnode *node, int n)
{
	int i;
	//m1,m2为当前还没用到的节点中权值最小和次小的权值
	int min1, min2;
	//l,r为每次构建一个父节点其左右儿子节点的序号
	int l, r;
	for (i = n + 1; i <= 2 * n - 1; i++)
	{
		min1 = min2 = 32767;
		l = r = 0;
		int k;
		for (k = 1; k <= i - 1; k++)
			if (node[k].parent == 0)
			{
				if (node[k].w < min1)
				{
					min2 = min1;
					r = l;
					min1 = node[k].w;
					l = k;
				}
				else if (node[k].w < min2)
				{
					min2 = node[k].w;
					r = k;
				}
			}
		node[i].w = node[l].w + node[r].w;
		node[i].lchild = l;
		node[i].rchild = r;
		node[l].parent = i;
		node[r].parent = i;
	}
}

//求每个节点的哈夫曼编码
void createHFMcode(HFMnode *node, HFMcode *hcode, int n)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		HFMcode d;
		//哈夫曼树最大层数就是元素的个数
		d.start = n;
		int num = i;
		int father = node[num].parent;
		while (father != 0)
		{
			if (node[father].lchild == num)
				d.code[d.start--] = '0';
			else
				d.code[d.start--] = '1';
			num = father;
			father = node[num].parent;
		}
		hcode[i] = d;
	}
}

void DeCoding(HFMnode* HT, int n)
{
	int len, i, p;
	char str[1000];
	cout << "请输入相应的霍夫曼编码" << endl;
	cin >> str;
	len = strlen(str);
	cout << "译码的结果为:" << endl;
	for (i = 0; i < len;) {
		p = 2 * n - 1;
		while (HT[p].lchild != 0 && HT[p].rchild != 0) {
			if (str[i] == '0') p = HT[p].lchild;
			if (str[i] == '1') p = HT[p].rchild;
			i++;
		}
		cout << HT[p].Data;
	}
	cout << endl;
}

//打印每个节点的编码
void printHFMcode(HFMnode * node, HFMcode * hcode, int n)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		cout << node[i].Data << " :";
		for (int k = hcode[i].start + 1; k <= n; k++)
			cout << hcode[i].code[k];
		cout << endl;
	}
}

int main(int argc, char* argv[])
{
	HFMnode node[2 * MAX];
	HFMcode hcd[MAX];

	cout << "请输入元素个数:" << endl;
	int n;
	cin >> n;
	int i;
	for (i = 1; i <= n; i++)
	{
		cout << "输入第" << i << "个节点的值与权重: " ;
		cin >> node[i].Data;
		cin >> node[i].w;
	}
	for (i = 1; i <= 2 * n - 1; i++)
	{
		node[i].parent = node[i].lchild = node[i].rchild = 0;
	}
	//建立哈夫曼树
	createHFMtree(node, n);
	//求每个节点的哈夫曼编码
	createHFMcode(node, hcd, n);
	//打印每个节点的编码
	cout << "输出每个节点的哈夫曼编码:" << endl;
	printHFMcode(node, hcd, n);
	//打印所得霍夫曼译码
	DeCoding(node, n);

	system("pause");
	return 0;
}

**

书本版本

**

#include<iostream>
#define MAX 200
using namespace std;
typedef char ElementType;

typedef struct {
	ElementType Data;
	int w;
	int parent, lchild, rchild;
}HFMTNode;

//每个节点的编码
//code存储编码
//start存储编码是从code数组的第几个开始
//在编码过程中从叶子节点向根节点逆推
struct HFMTcode
{
	char code[MAX];
	int start;
};
//建立哈夫曼树
void CreateHFMTree(HFMTNode Ht[], int N)
{
	int i, k, lmin, rmin;
	int min1, min2;
	for (i = 1; i < 2 * N; i++)
	{
		Ht[i].parent = Ht[i].lchild = Ht[i].rchild = 0;
		for (i = N + 1; i < 2*N; i++)
		{
			min1 = min2 = MAX;
			lmin = rmin = 0;
			for (k = 1; k <= i - 1; k++)
				if (Ht[k].parent == 0)
				{
					if (Ht[k].w < min1)
					{
						min2 = min1;
						rmin = lmin;
						min1 = Ht[k].w;
						lmin = k;
					}
					else if (Ht[k].w < min2)
					{
						min2 = Ht[k].w;
						rmin = k;
					}
				}
			Ht[lmin].parent = i;
			Ht[rmin].parent = i;
			Ht[i].w = Ht[lmin].w + Ht[rmin].w;
			Ht[i].lchild = lmin;
			Ht[i].rchild = rmin;
		}
	}
}

//求每个节点的哈夫曼编码
void createHFMcode(HFMTNode *node, HFMTcode *hcode, int n)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		HFMTcode d;
		//哈夫曼树最大层数就是元素的个数
		d.start = n;
		int num = i;
		int father = node[num].parent;
		while (father != 0)
		{
			if (node[father].lchild == num)
				d.code[d.start--] = '0';
			else
				d.code[d.start--] = '1';
			num = father;
			father = node[num].parent;
		}
		hcode[i] = d;
	}
}

void DeCoding(HFMTNode* HT, int n)
{
	int len, i, p;
	char str[1000];
	cout << "请输入相应的霍夫曼编码" << endl;
	cin >> str;
	len = strlen(str);
	cout << "译码的结果为:" << endl;
	for (i = 0; i < len;) {
		p = 2 * n - 1;
		while (HT[p].lchild != 0 && HT[p].rchild != 0) {
			if (str[i] == '0') p = HT[p].lchild;
			if (str[i] == '1') p = HT[p].rchild;
			i++;
		}
		cout << HT[p].Data;
	}
	cout << endl;
}

//打印每个节点的编码
void printHFMcode(HFMTNode * node, HFMTcode * hcode, int n)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		cout << node[i].Data << " :";
		for (int k = hcode[i].start + 1; k <= n; k++)
			cout << hcode[i].code[k];
		cout << endl;
	}
}

int  main(int argc, char* argv[])
{
	HFMTNode node[2 * MAX];
	HFMTcode hcd[MAX];

	cout << "请输入元素个数:" << endl;
	int n;
	cin >> n;
	int i;
	for (i = 1; i <= n; i++)
	{
		cout << "输入第" << i << "个节点的值与权重: ";
		cin >> node[i].Data;
		cin >> node[i].w;
	}
	for (i = 1; i <= 2 * n - 1; i++)
	{
		node[i].parent = node[i].lchild = node[i].rchild = 0;
	}
	//建立哈夫曼树
	CreateHFMTree(node, n);
	//求每个节点的哈夫曼编码
	createHFMcode(node, hcd, n);
	//打印每个节点的编码
	cout << "输出每个节点的哈夫曼编码:" << endl;
	printHFMcode(node, hcd, n);

	DeCoding(node, n);

	system("pause");
	return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值