Huffman编码

#include<stdio.h>
#include<stdlib.h>

struct node {
	char c;
	float p;
	int lchild;
	int rchild;
	int parent;
	int index;
};

void swap(node& a, node& b) {
	node temp;
	temp = a;
	a = b;
	b = temp;
}

void minHeapify(node arr[], int n, int i) {
	int smallest = i; // 初始化根节点为最小值
	int left = 2 * i + 1; // 左子节点
	int right = 2 * i + 2; // 右子节dian

	// 如果左子节点小于根节点,将其设为最小值
	if (left < n && arr[left].p < arr[smallest].p)
		smallest = left;
	// 如果右子节点小于当前最小值,将其设为最小值
	if (right < n && arr[right].p < arr[smallest].p)
		smallest = right;
	// 如果最小值不是根节点,交换根节点与最小值的位置,并进行递归调整
	if (smallest != i) {
		swap(arr[i], arr[smallest]);
		minHeapify(arr, n, smallest);
	}
}

// 生成最小堆
void make_heap(node arr[], int n) {
	int i;
	// 从最后一个非叶节点开始向上调整每个节点
	for (i = n / 2 - 1; i >= 0; i--)
		minHeapify(arr, n, i);
}

// 删除最小元素并调整为新的最小堆
node delete_min(node H[], int& n) {
	node min = H[0];
	H[0] = H[n - 1];
	n = n - 1;
	minHeapify(H, n, 0);
	return min;
}

void insert(node H[], int& n, node x) {
	n = n + 1;
	H[n-1] = x;
	int i = n-1;
	bool done = false;
	while (!done && i != 0) {
		if (H[i].p < H[i / 2].p)
			swap(H[i], H[i / 2]);
		else done = true;
		i = i / 2;
	}
}

void Huffman(char C[], float p[], int n, struct node T[], node H[]) {
	struct node  x, y, u;
	int i, m = n;
	//初始化T,H
	for (i = 0; i < n; i++) {
		T[i].c = H[i].c = C[i];
		T[i].p = H[i].p = p[i];
		T[i].lchild = T[i].rchild = T[i].parent = -1;
		H[i].index = i;
	}

	make_heap(H, n);
	for (i = 0; i < n - 1; i++) {
		x = delete_min(H, m);
		y = delete_min(H, m);
		u.p = x.p + y.p;
		u.index = n + i;
		insert(H, m, u);
		T[n + i].lchild = x.index;
		T[n + i].rchild = y.index;
		T[n + i].parent = -1;
		T[x.index].index = 0;
		T[y.index].index = 1;
		T[x.index].parent = T[y.index].parent = n + i;
	}
}

int main() {
	int n = 8;
	char C[8] = { 'a','b','c','d','e','f','g','h' };
	float p[8] = { 43,23,16,8,5,2,2,1 };
	node T[15], H[8],x;//T存放二叉树结点,H存放二叉树相关结点的堆
	Huffman(C, p, n, T, H);
	for (int i = 0; i < 8; i++) {//输出的实际是逆序
		x = T[i];
		printf("%c:\t", x.c);
		while (x.parent != -1) {
			printf("%d",x.index);
			x = T[x.parent];
		}
		printf("\n");
	}
	return 0;
}
#include<stdio.h>
#include<stdlib.h>


//测试huffman编码
void swap0(int& a, int& b) {
	int temp;
	temp = a;
	a = b;
	b = temp;
}

void minHeapify0(int arr[], int n, int i) {
	int smallest = i; // 初始化根节点为最小值
	int left = 2 * i + 1; // 左子节点
	int right = 2 * i + 2; // 右子节dian

	// 如果左子节点小于根节点,将其设为最小值
	if (left < n && arr[left] < arr[smallest])
		smallest = left;
	// 如果右子节点小于当前最小值,将其设为最小值
	if (right < n && arr[right] < arr[smallest])
		smallest = right;
	// 如果最小值不是根节点,交换根节点与最小值的位置,并进行递归调整
	if (smallest != i) {
		swap0(arr[i], arr[smallest]);
		minHeapify0(arr, n, smallest);
	}
}

// 生成最小堆
void make_heap0(int arr[], int n) {
	int i;
	// 从最后一个非叶节点开始向上调整每个节点
	for (i = n / 2 - 1; i >= 0; i--)
		minHeapify0(arr, n, i);
}

// 删除最小元素并调整为新的最小堆
int delete_min0(int H[], int& n) {
	int min = H[0];
	H[0] = H[n - 1];
	n = n - 1;
	minHeapify0(H, n, 0);
	return min;
}

void insert0(int H[], int& n, int x) {
	n = n + 1;
	H[n - 1] = x;
	int i = n - 1;
	bool done = false;
	while (!done && i != 0) {
		if (H[i] < H[i / 2])
			swap0(H[i], H[i / 2]);
		else done = true;
		i = i / 2;
	}
}

int main() {
	int n = 8;
	int p[8] = { 43,23,16,8,5,2,2,1 },t[15];
	make_heap0(p, n);
	for (int i = 0; i < n; i++) {
		t[i]=p[i];
	}
	for (int i = 0; i < 7; i++) {
		int x = delete_min0(p, n);
		int y = delete_min0(p, n);
		int u = x + y;
		t[8 + i] = u;
		insert0(p, n, u);
		
	}
	for (int i = 0; i < 15; i++){
		printf("%d\t", t[i]);
	}
	/*printf("\n");
	printf("%d,%d,%d,%d", c, ce, cd, n);
	for (int i = 0; i < n; i++) {
		printf("%d\t", p[i]);}*/
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值