数据结构---霍夫曼编码

霍夫曼编码算法的实现

从键盘输入字符序列及对应的权重,输出霍夫编码

分析:

  • 构造树结点,输入带编码字符及对应的权值;
  • 在树结点中选择parent = 0, 且权值最小的两个结点
  • 构造Huffman树并求出编码

代码:


#include "pch.h"
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

#define N 10 //树中叶子结点的最大数目
#define M (2*N-1)//树中结点的最大数目

typedef struct Node
{
	int weight;//权重
	int parent, lchild, rchild;//左右孩子及双亲

} HTNode;

typedef struct 
{
	char data;// 字符
	int weight; //权重
	char code[N];//编码
}HTCode;


void Init(HTCode * ht, int *n)
//初始化,从键盘读入n个字符及权值
{
	int i;
	printf("请输入带编码字符的个数:\n");
	scanf_s("%d",&(*n));
	rewind(stdin);
	printf("请输入带编码的字符:\n");
	for (i = 0; i < (*n); i++)
	{
		scanf_s("%c", &(ht[i].data));
	}
	rewind(stdin);
	printf("请输入带编码字符的权值:\n");
	for (i = 0; i < (*n); i++)
	{
		scanf_s("%d", &(ht[i].weight));
	}
	rewind(stdin);//清空缓冲区

}


void Select(HTNode *ht, int *s1, int *s2, int k)
/*从ht[0,1,2,...,k]结点中选择权值最小且parent=0的两个结点*/
{
	
	int i;
	for (i = 0; i < k; i++)
	{
		if (ht[i].parent == 0)
			break;
	}
	(*s1) = i;//找到第一个parent为零的点
	for (i = (*s1)+1; i < k; i++)
	{
		if (ht[i].parent == 0 && ht[i].weight < ht[(*s1)].weight)
		{
			(*s1) = i;
		}
	}
	for (i = 0; i < k; i++)
	{
		if (ht[i].parent == 0 && i != (*s1))
			break;
	}
	(*s2) = i;
	for (i = (*s2) + 1; i < k; i++)
	{
		if (ht[i].parent == 0 && i != (*s1) && ht[i].weight < ht[(*s2)].weight)
			(*s2) = i;
	}

}

void HuffmanCoding(HTNode *ht, HTCode *hc, int n)
/*构建霍夫曼树,并进行霍夫曼编码*/
{
	int s1, s2;
	int c, f;
	int Num_TreeNode = 2 * n - 1;// 总的结点数目
	int i;
	char code[N];
	int start;
	/*构建霍夫曼树*/
	for (i = 0; i < Num_TreeNode; i++) 
	{
		if(i<n)//前n个叶子结点
			ht[i].weight = hc[i].weight;
		ht[i].parent = 0;
		ht[i].rchild = ht[i].lchild = 0;	
	}
	for (i = n; i < Num_TreeNode; i++)
	{
		Select(ht, &s1, &s2, i );//从前n个结点中选择两个权值最小的结点
		ht[s1].parent =i;
		ht[s2].parent = i;
		ht[i].lchild = s1;
		ht[i].rchild = s2;
		ht[i].parent = 0;
		ht[i].weight = ht[s1].weight + ht[s2].weight;
	}
	/*进行霍夫编码,从叶子结点到根结点*/
	code[n] = '\0';
	for (i = 0; i < n; i++)
	{
		start = n ;
		for (c = i, f = ht[i].parent; f; c = f, f = ht[c].parent)//沿着叶子向根走
		{
			if (c == ht[f].lchild)
				code[--start] = '0';
			else 
				code[--start] = '1';
		}
		strcpy_s(hc[i].code, &code[start]);
	}
	
}

int main()
{
	HTNode ht[M+1];
	HTCode hc[N+1];
	int n;// 叶子结点个数
	Init(hc, &n);//初始化
	HuffmanCoding(ht, hc, n);
	int i;
	for (i = 0; i < n; i++)
	{
		printf("%c-----%s\n", hc[i].data, hc[i].code);
	}
	return 0;
}

程序运行截图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38904904/article/details/89240516