作业11-最优前缀码

1.问题

问题:给定字符集 C={x1,x2,…xn}和每个字符的频率f(xi) ,求关于 C 的一个最优前缀码。

2.解析

构造最优前缀码的贪心算法就是哈夫曼算法(Huffman)。
哈夫曼树的基本思想:选择权值小的叶子离根距离远些。

实现:
第一步:以每个结点作为根,构造只有一个根结点的n棵二叉树,根的权值就是结点的权。
第二步:在所有二叉树中选择根的权值最小的两棵二叉树作为左右子树构造一棵新的二叉树,根的权值等于其左右子树的根的权值之和。
第三步:去掉选中的二叉树、加入新生成的二叉树。
第四步:重复2、3步,直至只剩下一棵树为止。
作业11-最优前缀码_第1张图片
作业11-最优前缀码_第2张图片

3.设计

//构造哈夫曼树
HfTree create_HfTree(int* w, int n)
{
	int total = 2 * n - 1;
	HfTree HT = (HfTree)malloc(total * sizeof(HTNode));
	for (i = 0; i < n; i++){
		HT[i].parent = HT[i].lchild = HT[i].rchild = -1;
		HT[i].weight = *w;
		w++;
	}
	for (; i < total; i++){
		HT[i].parent = HT[i].lchild = HT[i].rchild = -1;
		HT[i].weight = 0;
	}
	int min1, min2;//用于保存每次循环选出的两个weight最小且parent为0的节点
	for (i = n; i < total; i++){
		select(HT, i, min1, min2);
		HT[min1].parent = i;
		HT[min2].parent = i;
		HT[i].lchild = min1;
		HT[i].rchild = min2;
		HT[i].weight = HT[min1].weight + HT[min2].weight;
	}
	return HT;
}

4.分析

O(nlogn)频率排序;for 循环 O(n),插入操作 O(logn)
算法时间复杂度是 O(n logn)

5.源码

https://github.com/chainessss/Algorithm-/blob/master/%E4%BD%9C%E4%B8%9A11-%E6%9C%80%E4%BC%98%E5%89%8D%E7%BC%80%E7%A0%81.cpp

你可能感兴趣的:(作业11-最优前缀码)