哈夫曼编码

#include<iostream>
using namespace std;
#include<stdio.h>
#include <string.h> 
#define MAX_CODE 10

class HNode{
public:
	char c;//节点的字符
	int weight;//节点的权重,即为出现的频率
	int lchild;//节点的左孩子的编号
	int rchild;//节点的右孩子的编号
	char code[MAX_CODE];//节点得到的编码
	HNode(){
		weight = -1;
		lchild = -1;
		rchild = -1;
	}
	
};

template <class Type>
void Swap(Type &a,Type &b){//交换a和b
	Type temp = a;
	a = b;
	b = temp;
}

int Partition(HNode a[],int p,int r){
	//将权重小于x的权重的点放在a[p]的左侧,
	//权重大于x的权重的点放在a[p]的右侧
	int i = p,j = r+1;
	HNode x = a[p];
	while (true){
		while(a[++i].weight < x.weight && i < r);
		while(a[--j].weight > x.weight);
		if(i >= j)
			break;
		Swap(a[i],a[j]);
	}
	a[p] = a[j];
	a[j] = x;
	return j;
}

void QuickSort(HNode a[],int p,int r){//p为a数组的第一个,r为最后一个
	if(p < r){
		int q = Partition(a,p,r);//得到的q为基准元素最后在数组中的位置
		QuickSort(a,p,q-1);//对左半段排序
		QuickSort(a,q+1,r);//对右半段排序
	}
}

void creatHuffmanTree(HNode a[],int num){
	//创建哈夫曼树,如果有num个节点需要被编码,则共需要开辟2*num-1个空间
	int left = 0;
	int right = num;
	for(int i = 0;i < num-1 && ((right+1) <= 2*num-1);i++){//需要循环num-1次确定num-1个度为2的节点,i < num-1
		QuickSort(a,left,right-1);//right-1,因为如果有6个节点,QuickSort时的第三个参数是5
		a[right].weight = a[left].weight + a[left+1].weight;
		a[right].c = '#';//表示非叶子节点
		a[right].lchild = left;
		a[right].rchild = left+1;
		left += 2;
		right += 1;
	}
}

void Encode(HNode a[],int index,int parent_index,char b = 'l'){
    //节点数组a的最后一个元素的下标是2*num-1
	if(parent_index == -1){
		a[index].code[0] = '\0';
	}
	else
	{
		if(b == 'l')//左孩子
		{
			strcpy(a[index].code,a[parent_index].code);
			strcat(a[index].code,"0");
		}
		
		if(b == 'r')//右孩子
		{
			strcpy(a[index].code,a[parent_index].code);
			strcat(a[index].code,"1");
		}
	}
	if(a[index].lchild != -1){
		Encode(a,a[index].lchild,index,'l');
	}
	if(a[index].rchild != -1){
		Encode(a,a[index].rchild,index,'r');
	}
	
}

void main(){
	int num;//节点数目
	num = 5;
	int numofspace = 9;//2*num-1
	HNode a[9];
	a[0].c = 'A';
	a[0].weight = 9;
	
	a[1].c = 'B';
	a[1].weight = 48;
	
	a[2].c = 'C';
	a[2].weight = 32;
	
	a[3].c = 'D';
	a[3].weight = 12;
	
	a[4].c = 'E';
	a[4].weight = 24;
	
	creatHuffmanTree(a,num);
	
	Encode(a,2*num-2,-1);//注意,为什么是2*num-2?根节点本来就不需要管了
	for(int i =0;i < 2*num-1;i++){//i < 2*num-1,为什么没有=?因为根节点本来就没有赋值
		if(a[i].c != '#')
			printf("%c:%s\n",a[i].c,a[i].code);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值