「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」。
哈夫曼算法
问题:给定一组权值,构造最优二叉树
想法-----哈夫曼算法的基本思想
- 初始化:由 n 个权值构造 n 棵只有一个根结点的二叉树,得到一个二叉树集合 F={T1,T2,…,Tn};
- 重复下述操作,直到集合 F 中只剩下一棵二叉树
- 选取与合并:在 F 中选取根结点的权值最小的两棵二叉树分别作为左右子树构造一棵新的二叉树,这棵新二叉树的根结点的权值为其左右子树根结点的权值之和;
- 删除与加入:在 F 中删除作为左右子树的两棵二叉树,并将新建立的二叉树加入到F中;
哈夫曼算法的运行实例
例 给定权值集合{2,4,5 ,3}
【算法——数据表示】如何存储哈夫曼树呢?
- 采用数组还是链表呢?
- n 个叶子结点--->合并 n-1 次--->n-1个分支结点
- 哈夫曼树共有 2n-1个结点--->设数组huffTree[2n-1]
- 须存储哪些关系呢?
- 选取根结点权值最小的二叉树--->存储parent信息
- 作为左右子树进行合并--->存储lchild和rchild信息
【算法——数据表示】如何存储哈夫曼树呢?
typedef struct
{
int weight; /*假定权值为整数*/
int parent, lchild, rchild;
} ElemType;
代码
void HuffmanTree(element huffTree[ ], int w[ ], int n ){
int i, k, i1, i2;
//初始化,所有结点均没有双亲和孩子
for (i = 0; i < 2*n-1; i++){
huffTree[i].parent = -1;
huffTree[i].lchild = -1;
huffTree[i].rchild = -1;
}
//构造n棵只含有根结点的二叉树
for (i = 0; i < n; i++)
huffTree[i].weight = w[i];
//n-1次合并
for (k = n; k < 2*n-1; k++){
//权值最小的两个根结点下标为i1和i2
Select(huffTree, i1, i2);
huffTree[k].weight = huffTree[i1].weight + huffTree[i2].weight;
huffTree[i1].parent = k;
huffTree[i2].parent = k;
huffTree[k].lchild = i1;
huffTree[k].rchild = i2;
}
}