哈夫曼编码横向打印

#include<stdio.h>  
#include<stdlib.h>  
#include<Windows.h>
#define MAXSIZE 30  
typedef struct
{
	char data;
	float weight;
	int parent;
	int lchild;
	int rchild;
}HTNode;
typedef struct
{
	char bits[10];
	int start;
}HCode;
void CreateHT(HTNode ht[30], int n)
{
	int i, k, lnode, rnode;
	int m = 2 * n - 1;
	float min1, min2;
	for (i = 0; i < m; i++)//对每个结点进行初始化  
	{
		ht[i].parent = -1; ht[i].lchild = -1;
		ht[i].rchild = -1; ht[i].weight = 0;
	}
	for (i = 0; i < n; i++)
	{//输入前n个结点的字符和权值  
		printf("输入第%d个字符和其权值,空格隔开\n", i + 1);
		getchar();
		scanf("%c %f", &ht[i].data, &ht[i].weight);
	}

	for (i = n; i < m; i++)
	{//构造哈夫曼树  
		min1 = min2 = 32767;
		lnode = rnode = -1;//lnode保存左子树的下标  
		for (k = 0; k <= i - 1; k++)
		{//在[0..i-1]中选择parent为-1且weight最小的两个结点
			if (ht[k].parent == -1)
			{
				if (ht[k].weight < min1)
				{
					min2 = min1;
					min1 = ht[k].weight;
					rnode = lnode;
					lnode = k;
				}
				else if (ht[k].weight < min2)
				{
					min2 = ht[k].weight;
					rnode = k;
				}
			}
		}
		ht[lnode].parent = i; ht[rnode].parent = i;
		ht[i].weight = ht[lnode].weight + ht[rnode].weight;
		ht[i].lchild = lnode; ht[i].rchild = rnode;
	}
}
void HuffmanCode(HTNode ht[], HCode hcd[], int n)//求编码  
{
	int i, p, c;
	HCode temp;//保存当前结点的信息  
	for (i = 0; i < n; i++)
	{
		temp.start = n;//  
		c = i;
		p = ht[i].parent;
		while (p != -1)
		{
			temp.start--;
			if (ht[p].lchild == c)
				temp.bits[temp.start] = '0';
			else
				temp.bits[temp.start] = '1';
			c = p;
			p = ht[p].parent;
		}
		hcd[i] = temp;
	}
}
void DeCode(HTNode ht[], int n)//译码  
{
		int i,m, j = 0,x=0;
		char b[MAXSIZE],B[MAXSIZE];
		m = 2*n - 1;
		i = m - 1;	//从根结点开始往下搜索
		printf("输入发送的编码(以'2'为结束标志):");
		fflush(stdin);//清理缓冲区
		gets(b);
		while (b[j] != '2')
		{
		
			if (b[j] == '0')
				i = ht[i].lchild;   //走向左孩子
			else
				i = ht[i].rchild;   //走向右孩子
			if (ht[i].lchild == -1)     //ht[i]是叶结点
			{
				B[x] = ht[i].data;
				B[x+1] = '\0';
				x++;
				i = m - 1;
			}
			j++;
		}
		if (ht[i].lchild == -1 || i == m - 1)
		{
			printf("译码后的字符为:");
			printf("%s", B);
		}
		else
		{
			printf("输入电文有误,请检查"); 
		}
	}//decode
int TreeDeep(HTNode ht[], int m)//求哈夫曼树的深度  
{
	int deep = 0;
	if (m != -1)
	{
		int LeafDeep = TreeDeep(ht, ht[m].lchild);
		int RightDeep = TreeDeep(ht, ht[m].rchild);
		deep = LeafDeep > RightDeep ? LeafDeep + 1 : RightDeep + 1;
	}
	return deep;
}
void PrintTree(HTNode ht[], int m, int depth)//横向打印哈夫曼树  
{
	int i;
	if (m != -1)
	{
		PrintTree(ht, ht[m].rchild, depth + 1);
		for (i = 0; i < depth; i++)printf("       ");
		if (ht[m].data != -52)printf("   -%c\n ", ht[m].data);
		else printf("   -%3.1f-▏\n", ht[m].weight);
		PrintTree(ht, ht[m].lchild, depth + 1);
	}
}
int main()
{
	int n, m, i, j, deep, cord;
	HTNode ht[MAXSIZE];
	HCode hcd[15];
	int ret = MessageBox(NULL,
		TEXT("\t★哈夫曼编/译码器★\n*******************************************\n*主要功能:  打印哈夫曼树  编码  译码*\n*******************************************\n*小组成*********************************\n\t  是否开始"), 
		TEXT("★哈夫曼编/译码器★"), MB_YESNO);

	if (ret == IDYES)
	{
		do
		{
			printf("\n\n①.创建哈夫曼树\n");
			printf("②.横向打印哈夫曼树\n");
			printf("③.输出编码\n");
			printf("④.读入电文,进行译码\n");
			printf("⑤.退出\n");
			scanf("%d", &cord);
			switch (cord)
			{
			case 1:
			{   printf("输入字符个数\n");
			scanf("%d", &n);
			CreateHT(ht, n);
			m = 2 * n - 1;
			}break;
			case 2:
			{
					  deep = TreeDeep(ht, m - 1);
					  PrintTree(ht, m - 1, deep);
			}break;
			case 3:
			{
					  HuffmanCode(ht, hcd, n);
					  for (i = 0; i < n; i++)
					  {
						  printf(" %c ", ht[i].data);
						  for (j = hcd[i].start; j < n; j++)
							  printf("%c", hcd[i].bits[j]);
						  printf("\n");
					  }
			}break;
			case 4:DeCode(ht, n); break;
			case 5:exit(0); break;
			}
		} while (cord < 5);
	}
	else
	{
		exit(0);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值