哈弗曼编码

数据压缩中的编码问题实验

#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)//所有无用树结点的Key都会被修改为-1
{
	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;//i相当于子结点下标,i/2相当于父结点下标 
	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插入最小值 
	}
	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;
}


运行截图

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值