1. 程式人生 > >c語言實現赫夫曼樹的構建以及生成赫夫曼編碼(《資料結構》演算法6.12)

c語言實現赫夫曼樹的構建以及生成赫夫曼編碼(《資料結構》演算法6.12)

這個程式是根據《資料結構》演算法6.12用c語言實現的程式,赫夫曼樹就不多說了,直接看程式碼,程式碼上都有註釋。

下面程式碼:

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#define MAX_NUM 100
#define inf 2000000000
using namespace std;
typedef struct {
	unsigned int weight;//權值 
	unsigned int parent,lchild,rchild;//父節點,孩子結點的權值 
}HTNode,*HuffmanTree;
typedef char * * HuffmanCode;//二維字元陣列 
int s1,s2;//最小的兩個結點 
void Select(HuffmanTree &HT,int x){//選出無父結點,並且權值最小的兩個結點,賦值給s1,s2 
	int i,min1=inf,min2=inf;
	for(i=1;i<=x;i++){//找最小 
		if(HT[i].weight<min1&&HT[i].parent==0){min1=HT[i].weight;s1=i;}
	}
	for(i=1;i<=x;i++){//找次小 
		if(HT[i].weight<min2&&i!=s1&&HT[i].parent==0){
			min2=HT[i].weight;s2=i;
		}
	}
}
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){//根據輸入的結點的權值和個數來構建赫夫曼樹 
	if(n<=1)return;
	int m=2*n-1;//n個葉子,有2*n-1個結點 
	int i;
	HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0號單元未用 
	HuffmanTree p;
	for(p=HT+1,i=1;i<=n;i++,p++,w++) {//葉子結點賦值 
	p->weight=*w;p->parent=0;p->lchild=0;p->rchild=0;
	}
	for(;i<=m;i++,p++) {//非葉子結點初始化 
	p->weight=0;p->parent=0;p->lchild=0;p->rchild=0;
	}
	for(i=n+1;i<=m;i++){
		Select(HT,i-1);//選出最小的兩個無父節點的結點 
		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 *));//申請一段以HC為首地址的記憶體,可以看成二維字元陣列 ,這裡先申請了第一維 
	char *cd=(char *)malloc(n*sizeof(char));//申請一段臨時工作空間 
	cd[n-1]='\0';//編碼結束符 
	for(i=1;i<=n;i++){
		int start=n-1,c,f;
		for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent){//從葉子到根逆向求編碼 
			if(HT[f].lchild==c)cd[--start]='0';//如果當前結點是父節點的左孩子,則存一個1 
			else cd[--start]='1';//反之 
		}
		HC[i]=(char *)malloc((n-start)*sizeof(char));//申請第二維 
		strcpy(HC[i],&cd[start]);//將編碼從工作空間存入赫夫曼編碼表中 
	}
	free(cd); //釋放臨時空間 
}
int main(){
	HuffmanTree HT;
	HuffmanCode HC;
	int w[MAX_NUM],n;
	printf("輸入結點的個數:\n"); 
	scanf("%d",&n);
	printf("輸入每個結點的權值:\n");
	for(int i=0;i<n;i++)
	scanf("%d",&w[i]);
	HuffmanCoding(HT,HC,w,n);
	for(int i=1;i<=n;i++)
	printf("%d的赫夫曼編碼為:%s\n",HT[i].weight,HC[i]);
	return 0;
}