创建顺序存储结构的哈夫曼树,其中找两个最小值要考虑蛮多的(C语言)

 

构造哈夫曼树算法

听的是哔哩哔哩上青岛大学王卓老师讲的数据结构

顺序存储结构的哈夫曼树大致是下面这个表类似的结构,有n个已知的位权,要求这个表,

表大致为

077361d414064bb1bbea44903b8b9e25.png

以下图片都是算法概括

基本思路

15234c40fe154737a5eb860c3c07ad1d.png

 算法(伪代码)

dafd99189d1d48aebd67396febcbd2b8.png4fdae0cb5a5d437193ef8b1e95c7b985.png

以下是本人写的代码

其中那个select_twomin函数我想了好久,这个查找两个最小值的算法考虑的东西蛮多的。

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

typedef struct{
	int weight;
	int parent;
	int lch;
	int rch;
}Node,*node;// 定义哈夫曼树一个节点 


//创建哈夫曼树 
node createhafumatree(int n){
	node tree = (node)malloc(sizeof(Node)*(2*n-1));
	if(!tree){
		exit(-1);
	}
	for(int i = 0;i < 2*n-1;i++){
		tree[i].lch = tree[i].rch = tree[i].parent = -1;
		if(i < n){
			printf("\n请输入%d位置上的位权:",i);
			scanf("%d",&tree[i].weight);
		}
	}
	
	for(int i = n;i < 2*n-1;i++){
		int min1,min2;
		select_twomin(tree,i,&min1,&min2);
		printf("min1 = %d,min2 = %d\n",min1,min2);
		tree[i].weight = tree[min1].weight + tree[min2].weight;
		tree[i].lch = min1;
		tree[i].rch = min2;
		tree[min1].parent = tree[min2].parent = i;
	}
	return tree;
} 

//select_twomin:选择并赋值两个较小的数 
void select_twomin(node t,int n,int* k1,int* k2){
	int i = 0;
	while(t[i].parent != -1){
		i++;
	}
	*k1 = i;
	i++;
	while(t[i].parent != -1){
		i++;
	}
	*k2 = i;
	i++;
	if(t[*k1].weight > t[*k2].weight){
		int t = *k1;
		*k1 = *k2;
		*k2 = t;
	}
	while(i < n){
		if(t[i].parent == -1){
			if(t[i].weight < t[*k1].weight){
				*k2 = *k1;
				*k1 = i;
			}else if(t[i].weight < t[*k2].weight){
				*k2 = i;
			}
			
		}
		i++;
	}
}

void traveltree(node t,int n){
	printf("number\tweight\tprarent\tleft\tright(prarent,left,right都为下标)");
	putchar('\n');
	for(int i = 0;i < 2*n-1;i++){
		printf("%d\t%d\t%d\t%d\t%d",i,t[i].weight,t[i].parent,t[i].lch,t[i].rch);
		putchar('\n');
	}
}


int main(){
	printf("请输入节点数:");
	int n;
	scanf("%d",&n); 
	node t = createhafumatree(n);
	traveltree(t,n);
}

运行结果

ed28e70043fd4d60b6717a0bf2323a0f.png

 

 

 

 

 

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言顺序存储结构(数组)方式创建哈夫曼树的步骤: 1. 定义哈夫曼树结构体和哈夫曼编码结构体: ```c #define MAXBIT 100 #define MAXVALUE 10000 #define MAXLEAF 30 #define MAXNODE MAXLEAF*2 -1 typedef struct { int weight; int parent; int lchild; int rchild; }HTNode, *HuffmanTree; typedef struct { int bit[MAXBIT]; int start; char ch_value; }HCodeType, *HuffmanCode; ``` 2. 初始化哈夫曼树: ```c void InitHuffmanTree(HuffmanTree *HT, int *n) { int i; *n = 0; *HT = (HuffmanTree)malloc(MAXNODE * sizeof(HTNode)); for (i = 0; i < MAXNODE; i++) { (*HT)[i].weight = 0; (*HT)[i].parent = -1; (*HT)[i].lchild = -1; (*HT)[i].rchild = -1; } } ``` 3. 构造哈夫曼树: ```c void CreateHuffmanTree(HuffmanTree *HT, int n, int *w) { int i, j, k; int min1, min2; for (i = 0; i < n; i++) { (*HT)[i].weight = w[i]; } for (i = n; i < 2 * n - 1; i++) { (*HT)[i].weight = 0; } for (i = n; i < 2 * n - 1; i++) { min1 = min2 = MAXVALUE; k = 0; for (j = 0; j < i; j++) { if ((*HT)[j].parent == -1) { if ((*HT)[j].weight < min1) { min2 = min1; min1 = (*HT)[j].weight; k = j; } else if ((*HT)[j].weight < min2) { min2 = (*HT)[j].weight; } } } (*HT)[k].parent = i; (*HT)[i].lchild = k; (*HT)[i].weight += min1; k = 0; for (j = 0; j < i; j++) { if ((*HT)[j].parent == -1) { if ((*HT)[j].weight < min1) { min2 = min1; min1 = (*HT)[j].weight; k = j; } else if ((*HT)[j].weight < min2) { min2 = (*HT)[j].weight; } } } (*HT)[k].parent = i; (*HT)[i].rchild = k; (*HT)[i].weight += min2; } } ``` 4. 生成哈夫曼编码: ```c void CreateHuffmanCode(HuffmanTree HT, HuffmanCode *HC, int n) { int i, j, start; char c; *HC = (HuffmanCode)malloc((n + 1) * sizeof(HCodeType)); for (i = 1; i <= n; i++) { (*HC)[i].start = n; } for (i = 1; i <= n; i++) { start = n; j = i; c = HT[i].weight; while (HT[j].parent != -1) { if (HT[HT[j].parent].lchild == j) { (*HC)[i].bit[--start] = 0; } else { (*HC)[i].bit[--start] = 1; } j = HT[j].parent; } (*HC)[i].start = start; (*HC)[i].ch_value = c; } } ``` 5. 调用以上函数: ```c int main() { int i, n; int weight[MAXLEAF]; HuffmanTree HT; HuffmanCode HC; char ch[MAXLEAF]; printf("请输入叶子结点个数:"); scanf("%d", &n); printf("请输入%d个叶子结点的权值:\n", n); for (i = 0; i < n; i++) { scanf("%d", &weight[i]); } InitHuffmanTree(&HT, &n); CreateHuffmanTree(&HT, n, weight); CreateHuffmanCode(HT, &HC, n); printf("哈夫曼编码为:\n"); for (i = 1; i <= n; i++) { printf("%c的编码为:", HC[i].ch_value); for (int j = HC[i].start; j < n; j++) { printf("%d", HC[i].bit[j]); } printf("\n"); } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值