赫夫曼树

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


typedef struct{
	int weight;
	int parent, lchild,rchild;
}HTNode, *HuffmanTree;

typedef char ** HuffmanCode;

void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n);	//w存放n个字符的权值,构造赫夫曼书HT,并求出n个字符的赫夫曼编码HC
void select(const HuffmanTree &HT, int n, int &s1, int &s2);	//选择parent为0且weiht最小的两个结点,其序号分别为s1,s2

int main(){
	HuffmanTree HT;
	HuffmanCode HC;
	int i;
	const int n = 8;
	int weight[n] = {5,29,7,8,14,23,3,11};

	HuffmanCoding(HT, HC, weight, n);
	for(i=1; i<=n; i++)
		printf("%d %s\n",HT[i].weight, HC[i]);

	return 0;
}

void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){	//w存放n个字符的权值,构造赫夫曼书HT,并求出n个字符的赫夫曼编码HC
	int i,m,s1,s2;
//	HuffmanTree p;
	int start,f,c;//start指向当前编码位置,f为parent结点序号,c为当前的结点序号

	if(n <= 1)	return ;
	m = 2*n-1;
	HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));	//0号单元未用
	memset(HT,0,(m+1)*sizeof(HTNode));

	for(i=1; i<=n; ++i, ++w)	HT[i].weight = *w;
	for(i = n+1; i<=m; i++){	//建赫夫曼树
		select(HT, i-1, s1, s2);
		HT[s1].parent = i;	HT[s2].parent = i;
		HT[i].lchild = s1;	HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
	
	//求赫夫曼编码
	HC = (HuffmanCode)malloc((n+1) * sizeof(char *));	//分配n个字符编码的头指针向量
	char *cd = (char *)malloc(n * sizeof(char));	//分配求编码的工作空间
	cd[n-1] = '\0';//编码结束符
	for(i=1; i<=n; i++){	//逐个字符求赫夫曼编码
		start = n-1;//编码结束符位置
		for(c=i, f=HT[i].parent; f!=0; c=f, f=HT[f].parent)	//从叶子到根你想求编码
			if(HT[f].lchild == c)	cd[--start] = '0';
			else	cd[--start] = '1';
			HC[i] = (char *)malloc((n-start) * sizeof(char));	//为第i个字符编码分配空间
			strcpy(HC[i], &cd[start]);	//从cd复制编码到HC
	}
	free(cd); 
}

void select(const HuffmanTree &HT, int n, int &s1, int &s2){	//选择parent为0且weiht最小的两个结点,其序号分别为s1,s2
	if(n < 1) return ;
	int i,min1,min2;	//min1为最小,min2为第二小
	int ic=0;	//主要用来处理初始时的情况 和 当!=0 的数仅剩2个的情况
	for(i=1; i<=n; i++){
		if(HT[i].parent != 0)	continue;
		if(ic == 0){
			min1 = i; min2 = i;	ic++;
		}
		else if(ic == 1){
			if(HT[min1].weight > HT[i].weight){
				min2 = min1;	min1 = i;	ic++;
			}
			else{
				min2 = i;	ic++;
			}
		}
		else{
			if(HT[min1].weight > HT[i].weight){
					min2 = min1;
					min1 = i;
			}
			else if(HT[min2].weight > HT[i].weight)	min2= i;
			else if(HT[min2].weight == HT[i].weight && min1 == min2)	min2 = i;
		}
	}
	s1 = min1;	s2 = min2;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值