原文链接:https://blog.csdn.net/Authur520/article/details/84781037?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1
最小堆建哈夫曼树
测试用例:
5
1 2 3 4 5
#include<stdio.h>
#include<stdlib.h>
#define MinData -10001
typedef struct Heap *MinHeap;
typedef struct HTNode *HuffmanTree;
struct Heap{
HuffmanTree *data;
int Size;
int Capacity;
};
struct HTNode{
int Weight;
HuffmanTree Left;
HuffmanTree Right;
};
MinHeap CreateMinHeap(int MaxSize);
bool Insert(MinHeap H,HuffmanTree item);
HuffmanTree DeleteMin(MinHeap H);
MinHeap BuildMinHeap(MinHeap H);
HuffmanTree Huffman(MinHeap H);
void PreOrderTraversal(HuffmanTree BST);
void Inorder(HuffmanTree BST);
bool IsFull(MinHeap H);
bool IsEmpty(MinHeap H);
int main()
{
int i,N;
MinHeap H;
HuffmanTree T,BT=NULL;
printf("请输入叶子结点的个数:\n");
scanf("%d",&N);
H=CreateMinHeap(2*N);
printf("请输入%d个叶子结点对应的权值:\n",N);
for(i=1; i<=N; i++){
T=(HuffmanTree)malloc(sizeof(struct HTNode));
T->Weight = 0;
T->Left = T->Right = NULL;
scanf("%d",&(T->Weight));
H->data[++(H->Size)] = T;
}
BT = Huffman(H);
printf("先序遍历此哈夫曼树的权值:\n");
PreOrderTraversal(BT);
puts("");
printf("中序遍历此哈夫曼树的权值:\n");
Inorder(BT);
return 0;
}
HuffmanTree Huffman(MinHeap H)
{
int i,N;
HuffmanTree T;
BuildMinHeap( H );
N=H->Size;
for(i=1;i<N;i++)
{
T=(HuffmanTree)malloc(sizeof(struct HTNode));
T->Weight = 0;
T->Left = T->Right = NULL;
T->Left=DeleteMin(H);
T->Right=DeleteMin(H);
T->Weight=T->Left->Weight+T->Right->Weight;
Insert(H,T);
}
return DeleteMin(H);
}
MinHeap CreateMinHeap(int MaxSize)
{
MinHeap H = (MinHeap)malloc(sizeof(struct Heap));
H->data = (HuffmanTree*)malloc((MaxSize+1)*sizeof(HuffmanTree));
H->Size = 0;
H->Capacity = MaxSize;
HuffmanTree T=(HuffmanTree)malloc(sizeof(struct HTNode));
T->Weight = 0;
T->Left = T->Right = NULL;
T->Weight=MinData;
H->data[0] =T;
return H;
}
bool IsFull(MinHeap H)
{
return (H->Size==H->Capacity);
}
bool IsEmpty(MinHeap H)
{
return (H->Size==0);
}
bool Insert(MinHeap H,HuffmanTree item)
{
int i;
if( IsFull(H) ){
printf("最小堆已满\n");
return false;
}
i = ++H->Size;
for(; H->data[i/2]->Weight > item->Weight; i/=2)
H->data[i] = H->data[i/2];
H->data[i] = item;
return true;
}
HuffmanTree DeleteMin(MinHeap H)
{
int parent,child;
HuffmanTree MinItem,temp = NULL;
if( IsEmpty(H) ){
printf("最小堆为空\n");
return NULL;
}
MinItem = H->data[1];
temp = H->data[H->Size--];
for(parent=1; parent*2<=H->Size; parent=child){
child = parent*2;
if((child != H->Size) && (H->data[child]->Weight > H->data[child+1]->Weight)){
child++;
}
if(temp->Weight > H->data[child]->Weight){
H->data[parent] = H->data[child];
}else{
break;
}
}
H->data[parent] = temp;
return MinItem;
}
MinHeap BuildMinHeap(MinHeap H)
{
int i,parent,child;
HuffmanTree temp;
for(i=H->Size/2;i>0;i--){
temp = H->data[i];
for(parent=i; parent*2<=H->Size; parent=child){
child = parent*2;
if((child != H->Size) && (H->data[child]->Weight > H->data[child+1]->Weight)){
child++;
}
if(temp->Weight > H->data[child]->Weight){
H->data[parent] = H->data[child];
}else{
break;
}
}
H->data[parent] = temp;
}
return H;
}
void PreOrderTraversal(HuffmanTree BST)
{
if( BST ){
printf("%d ",BST->Weight);
PreOrderTraversal(BST->Left);
PreOrderTraversal(BST->Right);
}
}
void Inorder(HuffmanTree BST)
{
if(BST)
{
Inorder(BST->Left);
printf("%d ",BST->Weight);
Inorder(BST->Right);
}
}
增加了哈夫曼编码、解码
测试用例:
6
6 3 8 2 10 4
a b c d e f
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MinData -10001
typedef struct TreeNode *HuffmanTree;
typedef struct TreeNode{
char ch;
int Weight;
HuffmanTree Left;
HuffmanTree Right;
}HuffmanNode;
typedef struct HeapStruct *MinHeap;
struct HeapStruct{
HuffmanTree *data;
int Size;
int Capacity;
};
HuffmanTree NewHuffmanNode();
MinHeap CreateMinHeap(int MaxSize);
bool Insert(MinHeap H,HuffmanTree item);
HuffmanTree DeleteMin(MinHeap H);
MinHeap BuildMinHeap(MinHeap H);
HuffmanTree Huffman(MinHeap H);
void PreOrderTraversal(HuffmanTree BST);
void HuffmanCode(HuffmanTree BST,int depth);
int main()
{
int i,N;
MinHeap h;
HuffmanTree T,BT = NULL;
printf("请输入叶子结点的个数:\n");
scanf("%d",&N);
h = CreateMinHeap(2*N);
printf("请输入%d个叶子结点对应的权值:\n",N);
for(i=1; i<=N; i++){
T = NewHuffmanNode();
scanf("%d",&(T->Weight));
h->data[++(h->Size)] = T;
}
char string[100];
printf("请连续输入这%d个叶子结点各自代表的字符:\n",N);
getchar();
gets(string);
for(i=1; i<=h->Size; i++){
h->data[i]->ch= string[i-1];
}
BT = Huffman(h);
printf("\n");
HuffmanCode(BT,0);
return 0;
}
HuffmanTree Huffman(MinHeap H)
{
int i,num;
HuffmanTree T;
BuildMinHeap( H );
num = H->Size;
for(i=1; i<num; i++){
T = NewHuffmanNode();
T->Left = DeleteMin(H);
T->Right = DeleteMin(H);
T->Weight = T->Left->Weight+T->Right->Weight;
Insert(H,T);
}
T = DeleteMin(H);
return T;
}
void HuffmanCode(HuffmanTree BST,int depth)
{
static int code[10];
if( BST ){
if( (BST->Left == NULL) && (BST->Right == NULL)){
printf("字符%c的哈夫曼编码为:",BST->ch);
for(int i=0; i<depth; i++){
printf("%d",code[i]);
}
printf("\n");
}else{
code[depth] = 0;
HuffmanCode(BST->Left,depth+1);
code[depth] = 1;
HuffmanCode(BST->Right,depth+1);
}
}
}
HuffmanTree NewHuffmanNode()
{
HuffmanTree BST = (HuffmanTree)malloc(sizeof(HuffmanNode));
BST->Weight = 0;
BST->Left = BST->Right = NULL;
return BST;
}
MinHeap CreateMinHeap(int MaxSize)
{
MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));
H->data = (HuffmanTree *)malloc((MaxSize+1) * sizeof(HuffmanTree));
H->Size = 0;
H->Capacity = MaxSize;
HuffmanTree T = NewHuffmanNode();
T->ch = '\0';
T->Weight = MinData;
H->data[0] = T;
return H;
}
bool IsFull(MinHeap H)
{
return (H->Size == H->Capacity);
}
bool IsEmpty(MinHeap H)
{
return (H->Size == 0);
}
bool Insert(MinHeap H,HuffmanTree item)
{
int i;
if( IsFull(H) ){
printf("最小堆已满\n");
return false;
}
i = ++H->Size;
for(; H->data[i/2]->Weight > item->Weight; i/=2)
H->data[i] = H->data[i/2];
H->data[i] = item;
return true;
}
HuffmanTree DeleteMin(MinHeap H)
{
int parent,child;
HuffmanTree MinItem,temp = NULL;
if( IsEmpty(H) ){
printf("最小堆为空\n");
return NULL;
}
MinItem = H->data[1];
temp = H->data[H->Size--];
for(parent=1; parent*2<=H->Size; parent=child){
child = parent*2;
if((child != H->Size) && (H->data[child]->Weight > H->data[child+1]->Weight)){
child++;
}
if(temp->Weight > H->data[child]->Weight){
H->data[parent] = H->data[child];
}else{
break;
}
}
H->data[parent] = temp;
return MinItem;
}
MinHeap BuildMinHeap(MinHeap H)
{
int i,parent,child;
HuffmanTree temp;
for(i=H->Size/2;i>0;i--){
temp = H->data[i];
for(parent=i; parent*2<=H->Size; parent=child){
child = parent*2;
if((child != H->Size) && (H->data[child]->Weight > H->data[child+1]->Weight)){
child++;
}
if(temp->Weight > H->data[child]->Weight){
H->data[parent] = H->data[child];
}else{
break;
}
}
H->data[parent] = temp;
}
return H;
}