哈夫曼树及n皇后

目录

哈夫曼树:

n皇后问题:


 

哈夫曼树:

定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。

构建步骤如下:
    1、将给定的n个权值看做n棵只有根节点(无左右孩子)的二叉树,组成一个集合HT,每棵树的权值为该节点的权值。
    2、从集合HT中选出2棵权值最小的二叉树,组成一棵新的二叉树,其权值为这2棵二叉树的权值之和。
    3、将步骤2中选出的2棵二叉树从集合HT中删去,同时将步骤2中新得到的二叉树加入到集合HT中。
    4、重复步骤2和步骤3,直到集合HT中只含一棵树,这棵树便是赫夫曼树。
代码:

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

typedef double DataType; 

typedef struct HTNode 
{
	DataType weight; 
	int parent; 
	int lc, rc; 
}*HuffmanTree;

typedef char **HuffmanCode; 


void Select(HuffmanTree& HT, int n, int& s1, int& s2)
{
	int min;

	for (int i = 1; i <= n; i++)
	{
		if (HT[i].parent == 0)
		{
			min = i;
			break;
		}
	}
	for (int i = min + 1; i <= n; i++)
	{
		if (HT[i].parent == 0 && HT[i].weight < HT[min].weight)
			min = i;
	}
	s1 = min; 
	for (int i = 1; i <= n; i++)
	{
		if (HT[i].parent == 0 && i != s1)
		{
			min = i;
			break;
		}
	}
	for (int i = min + 1; i <= n; i++)
	{
		if (HT[i].parent == 0 && HT[i].weight < HT[min].weight&&i != s1)
			min = i;
	}
	s2 = min; }

//构建哈夫曼树
void CreateHuff(HuffmanTree& HT, DataType* w, int n)
{
	int m = 2 * n - 1;
	HT = (HuffmanTree)calloc(m + 1, sizeof(HTNode)); 
	for (int i = 1; i <= n; i++)
	{
		HT[i].weight = w[i - 1]; 
	}
	for (int i = n + 1; i <= m; i++) 
	{

		int s1, s2;
		Select(HT, i - 1, s1, s2); 
		HT[i].weight = HT[s1].weight + HT[s2].weight; 
		HT[s1].parent = i; 
		HT[s2].parent = i; 
		HT[i].lc = s1; 
		HT[i].rc = s2; 
	}

	printf("哈夫曼树为:>\n");
	printf("下标   权值     父结点   左孩子   右孩子\n");
	printf("0                                  \n");
	for (int i = 1; i <= m; i++)
	{
		printf("%-4d   %-6.2lf   %-6d   %-6d   %-6d\n", i, HT[i].weight, HT[i].parent, HT[i].lc, HT[i].rc);
	}
	printf("\n");
}

void HuffCoding(HuffmanTree& HT, HuffmanCode& HC, int n)
{
	HC = (HuffmanCode)malloc(sizeof(char*)*(n + 1));
	char* code = (char*)malloc(sizeof(char)*n); 
	code[n - 1] = '\0'; 
	for (int i = 1; i <= n; i++)
	{
		int start = n - 1; 
		int c = i; 
		int p = HT[c].parent; 
		while (p) 
		{
			if (HT[p].lc == c) 
				code[--start] = '0';
			else
				code[--start] = '1';
			c = p; 
			p = HT[c].parent;
		}
		HC[i] = (char*)malloc(sizeof(char)*(n - start)); 
		strcpy(HC[i], &code[start]); 
	}
	free(code); 
}

int main()
{
	int n = 0;
	printf("请输入数据个数:>");
	scanf("%d", &n);
	DataType* w = (DataType*)malloc(sizeof(DataType)*n);
	if (w == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	printf("请输入数据:>");
	for (int i = 0; i < n; i++)
	{
		scanf("%lf", &w[i]);
	}
	HuffmanTree HT;
	CreateHuff(HT, w, n); 

	HuffmanCode HC;
	HuffCoding(HT, HC, n); 

	for (int i = 1; i <= n; i++) 
	{
		printf("数据%.2lf的编码为:%s\n", HT[i].weight, HC[i]);
	}
	free(w);
	return 0;
}

n皇后问题:

代码:

#include <stdio.h>
#include <malloc.h>
#include <math.h>

bool place(int* paraSolution, int paraT){
	int j;
    for (j = 1; j < paraT; j ++){
        if ((abs(paraT - j) == abs(paraSolution[j] - paraSolution[paraT])) || (paraSolution[j] == paraSolution[paraT]))
            return false;
    }
    return true;
}
void backtracking(int* paraSolution, int paraN, int paraT){
	int i;
    if (paraT > paraN){
        for (i = 1; i <= paraN; i ++)
            printf("%d ", paraSolution[i]);
		printf("\r\n");
    }else{
        for (i = 1; i <= paraN; i ++){
            paraSolution[paraT] = i;
            if (place(paraSolution, paraT))
                backtracking(paraSolution, paraN, paraT + 1);
        }
    }
}
void nQueen(int paraN){
	int i;
	int* solution = (int*)malloc((paraN + 1) * sizeof(int));
	for (i = 0; i <= paraN; i ++)
		solution[i] = 0;

    backtracking(solution, paraN, 1);
}
int main(){
	nQueen(5);
	return 1;
}

运行结果:

1 3 5 2 4
1 4 2 5 3
2 4 1 3 5
2 5 3 1 4
3 1 4 2 5
3 5 2 4 1
4 1 3 5 2
4 2 5 3 1
5 2 4 1 3
5 3 1 4 2

--------------------------------
Process exited after 0.05853 seconds with return value 1
请按任意键继续. . .

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值