数据压缩中的编码问题实验
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define Minweight -1
typedef struct Node* ElementType;
struct Node {
int Weight;
char Key;
};
typedef struct HfTNode* HuffmanTree;
struct HfTNode {
ElementType Data;
HuffmanTree Left, Right;
};
typedef struct Heapstruct* MinHeap;
struct Heapstruct {
HuffmanTree* Elements;
int Size;
int Capacity;
};
typedef struct SNode* PtrToSNode;
struct SNode {
ElementType Data;
PtrToSNode Next;
};
typedef PtrToSNode Stack;
Stack CreateStack(void);
int IsEmpty_Stack(Stack);
void Push(Stack, ElementType);
ElementType Pop(Stack);
ElementType GetStackTop(Stack);
MinHeap CreateMinHeap(int MaxSize);
int IsEmpty_MinHeap(MinHeap H);
int IsFull_MinHeap(MinHeap H);
void Insert_MinHeap(MinHeap H, HuffmanTree Item);
HuffmanTree Delete_MinHeap(MinHeap H);
void MinMaking(MinHeap H, int Root);
void BuildMinHeap(MinHeap H);
HuffmanTree Huffman(MinHeap H);
void PrintPath(HuffmanTree T);
int main(void)
{
Stack S;
int MaxSize;
MinHeap H;
HuffmanTree T;
S = CreateStack();
do {
printf("输入关键字个数\n");
scanf("%d", &MaxSize);
getchar();
if (MaxSize <= 1)
printf("不必为%d个关键字编码\n");
else
break;
} while (1);
H = CreateMinHeap(MaxSize);
for (int i = 1; i <= MaxSize; i++) {
H->Elements[i] = (HuffmanTree)malloc(sizeof(struct HfTNode));
H->Elements[i]->Left = NULL;
H->Elements[i]->Right = NULL;
H->Elements[i]->Data = (ElementType)malloc(sizeof(struct HfTNode));
printf("输入关键字及出现频率\n");
scanf("%c %d", &H->Elements[i]->Data->Key, &H->Elements[i]->Data->Weight);
getchar();
}
T = Huffman(H);
printf("#######<Answar>#######\n");
PrintPath(T);
}
void PrintPath(HuffmanTree T)
{
HuffmanTree PtoT;
HuffmanTree Root;
char Word[10];
int i = 0;
while (T->Data->Key != -1) {
PtoT = T;
Root = PtoT;
i = 0;
while (1) {
if (!PtoT->Left && !PtoT->Right) {
Word[i++] = PtoT->Data->Key;
Word[i] = '\0';
printf("%s\n", Word);
PtoT->Data->Key = -1;
if ((!Root->Left || Root->Left->Data->Key == -1) && (!Root->Right || Root->Right->Data->Key == -1))
Root->Data->Key = -1;
break;
}
else if (PtoT->Left && PtoT->Left->Data->Key != -1) {
Word[i++] = '1';
Root = PtoT;
PtoT = PtoT->Left;
continue;
}
else if (PtoT->Right && PtoT->Right->Data->Key != -1) {
Word[i++] = '0';
Root = PtoT;
PtoT = PtoT->Right;
continue;
}
PtoT->Data->Key = -1;
break;
}
}
}
MinHeap CreateMinHeap(int MaxSize)
{
MinHeap H;
H = (MinHeap)malloc(sizeof(struct Heapstruct));
H->Elements = (HuffmanTree*)malloc(sizeof(HuffmanTree) * (MaxSize + 1));
H->Size = MaxSize;
H->Capacity = MaxSize;
H->Elements[0] = (HuffmanTree)malloc(sizeof(struct HfTNode));
H->Elements[0]->Data = (ElementType)malloc(sizeof(struct Node));
H->Elements[0]->Data->Weight = Minwight;
return H;
}
int IsEmpty_MinHeap(MinHeap H)
{
return (H->Size == 0);
}
int IsFull_MinHeap(MinHeap H)
{
return (H->Size == H->Capacity);
}
void Insert_MinHeap(MinHeap H, HuffmanTree Item)
{
int i;
if (IsFull_MinHeap(H)) return;
i = ++H->Size;
for (; H->Elements[i / 2]->Data->Weight > Item->Data->Weight; i /= 2)
H->Elements[i] = H->Elements[i / 2];
H->Elements[i] = Item;
}
HuffmanTree Delete_MinHeap(MinHeap H)
{
HuffmanTree Item, MinItem;
int Parent, Child;
if (IsEmpty_MinHeap(H))
return NULL;
MinItem = H->Elements[1];
Item = H->Elements[H->Size--];
for (Parent = 1; Parent * 2 <= H->Size; Parent = Child) {
Child = Parent * 2;
if (H->Elements[Child]->Data->Weight > H->Elements[Child + 1]->Data->Weight)
Child++;
if (H->Elements[Child]->Data->Weight > Item->Data->Weight)
break;
else
H->Elements[Parent] = H->Elements[Child];
}
H->Elements[Parent] = Item;
return MinItem;
}
void MinMaking(MinHeap H, int Root)
{
int Parent, Child;
HuffmanTree Item;
Item = H->Elements[Root];
for (Parent = Root; Parent * 2 <= H->Size; Parent = Child) {
Child = Parent * 2;
if (Child + 1 < H->Size && H->Elements[Child]->Data->Weight > H->Elements[Child + 1]->Data->Weight)
Child++;
if (H->Elements[Child]->Data->Weight > Item->Data->Weight)
break;
else
H->Elements[Parent] = H->Elements[Child];
}
H->Elements[Parent] = Item;
}
void BuildMinHeap(MinHeap H)
{
int i;
for (i = H->Size / 2; i >= 1; i--) {
MinMaking(H, i);
}
}
HuffmanTree Huffman(MinHeap H)
{
HuffmanTree T;
BuildMinHeap(H);
while (H->Size > 1) {
T = (HuffmanTree)malloc(sizeof(struct HfTNode));
T->Left = Delete_MinHeap(H);
T->Right = Delete_MinHeap(H);
T->Data = (ElementType)malloc(sizeof(struct Node));
T->Data->Weight = T->Left->Data->Weight + T->Right->Data->Weight;
Insert_MinHeap(H, T);
}
T = Delete_MinHeap(H);
return T;
}
Stack CreateStack(void)
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Next = NULL;
return S;
}
int IsEmpty_Stack(Stack S)
{
return (S->Next == NULL);
}
void Push(Stack S, ElementType Sdata)
{
PtrToSNode P;
P = (PtrToSNode)malloc(sizeof(struct SNode));
P->Data = Sdata;
P->Next = S->Next;
S->Next = P;
}
ElementType Pop(Stack S)
{
if (IsEmpty_Stack(S)) {
printf("The Stack is Empty.");
return NULL;
}
else {
PtrToSNode P;
ElementType Sdata;
P = S->Next;
Sdata = P->Data;
S->Next = P->Next;
free(P);
return Sdata;
}
}
ElementType GetStackTop(Stack S)
{
if (IsEmpty_Stack(S)) {
printf("The Stack is empty.");
return NULL;
}
else
return S->Next->Data;
}
