又来写解题报告了,这道题相比于前两道来说都要简单一些。
Huffman树的生成办法很简单:从指定节点堆中选出最小的两个节点作为左右子树,它们的和为父节点,将父节点加入节点堆,从节点堆中删除子树的节点。
程序的实现就是模拟上面的过程生成这棵二叉树。
其中要注意的一点就是如何选出最小的两个节点:我这里使用了C++中STL的Priority_Queue,这是一个现成的顺序队列,好用、省时。
就说这么多啦,也没啥说的了,AC代码奉上。
/* ID: Moien_Podiene LANG: C++ */ #include <iostream> #include <cstdlib> #include <queue> using namespace std; class BinTreeNode; class BinTreeNode { public: BinTreeNode(); //缺省构造函数 BinTreeNode(int); //由当前节点的变量值(参数)创建节点 BinTreeNode(int, BinTreeNode *, BinTreeNode *); ////由当前节点的变量值(参数1)、左右子树指针(参数2,3)创建节点 BinTreeNode *GetLeftChild(); //返回当前节点的左孩子指针 BinTreeNode *GetRightChild(); //返回当前节点的右孩子指针 BinTreeNode *SetLeftChild(BinTreeNode *); //由参数中的节点设置当前节点的左孩子,返回左孩子指针 BinTreeNode *SetRightChild(BinTreeNode *); //由参数中的节点设置当前节点的右孩子,返回右孩子指针 int GetData(); //获取节点值 int SetData(int); //设置节点值,返回设置的值 bool operator<(BinTreeNode); bool operator==(BinTreeNode); private: int data; //当前节点的值 BinTreeNode *leftChild; BinTreeNode *rightChild; }; int BinTreeNodeCompare(const void *, const void *); //比较节点数据大小 int WeighCalculate(BinTreeNode *, int); //计算外部路径长度和,参数2为当前深度 bool operator<(BinTreeNode, BinTreeNode); const int MAX_NUM = 256; //最大节点数 int main() { int caseNum; //测试数据组数 int originNum, nodeNum; //每组测试数据节点数,当前二叉树总结点数 int buff; //节点数据缓存 BinTreeNode *binBuff; //节点缓存 BinTreeNode binTree[MAX_NUM]; cin >> caseNum; for(int i = 0; i < caseNum; i++) { BinTreeNode leftTemp; //左子树缓存 BinTreeNode rightTemp; //右子树缓存 priority_queue<BinTreeNode> binTreeQueue; cin >> originNum; nodeNum = 0; for(int j = 0; j < originNum; j++) { cin >> buff; binBuff = new BinTreeNode(buff); binTreeQueue.push(*binBuff); delete binBuff; } for(int j = 0; j < originNum - 1; j++) { leftTemp = binTreeQueue.top(); binTreeQueue.pop(); rightTemp = binTreeQueue.top(); binTreeQueue.pop(); binTree[nodeNum++] = leftTemp; binTree[nodeNum++] = rightTemp; //队列顶的前两个元素即为最小的两个元素 binBuff = new BinTreeNode(leftTemp.GetData() + rightTemp.GetData(), &(binTree[nodeNum - 2]), &(binTree[nodeNum - 1])); binTreeQueue.push(*binBuff); if(j == originNum - 2) binTree[nodeNum++] = binTreeQueue.top(); delete binBuff; } qsort(binTree, nodeNum, sizeof(BinTreeNode), BinTreeNodeCompare); BinTreeNode *root = &binTree[nodeNum - 1]; cout << WeighCalculate(root, 0) << endl; } return 0; } BinTreeNode::BinTreeNode() { data = -1; leftChild = rightChild = NULL; } BinTreeNode::BinTreeNode(int val) { data = val; leftChild = rightChild = NULL; } BinTreeNode::BinTreeNode(int val, BinTreeNode *left, BinTreeNode *right) { data = val; leftChild = left; rightChild = right; } BinTreeNode *BinTreeNode::GetLeftChild() { return leftChild; } BinTreeNode *BinTreeNode::GetRightChild() { return rightChild; } BinTreeNode *BinTreeNode::SetLeftChild(BinTreeNode *val) { leftChild = val; return leftChild; } BinTreeNode *BinTreeNode::SetRightChild(BinTreeNode *val) { rightChild = val; return rightChild; } int BinTreeNode::GetData() { return data; } int BinTreeNode::SetData(int val) { data = val; return data; } bool BinTreeNode::operator<(BinTreeNode x) { return data > x.GetData(); //与小于判断相反,达成队列由小到大排列的目的 } bool BinTreeNode::operator==(BinTreeNode x) { if(data != x.GetData()) return false; else if(leftChild != x.GetLeftChild()) return false; else if(rightChild != x.GetRightChild()) return false; return true; } int BinTreeNodeCompare(const void *x, const void *y) { return ((BinTreeNode *)x) -> GetData() - ((BinTreeNode *)y) -> GetData(); } int WeighCalculate(BinTreeNode *root, int level) { if(root == NULL) return 0; if(root -> GetLeftChild() == NULL && root -> GetRightChild() == NULL) //递归出口,叶节点 return root -> GetData() * level; return WeighCalculate(root -> GetLeftChild(), level + 1) + WeighCalculate(root -> GetRightChild(), level + 1); //递归求左右子树深度和 } bool operator<(BinTreeNode x, BinTreeNode y) { return x.GetData() > y.GetData(); }
Huffman编码树 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65535kB 描述 构造一个具有n个外部节点的扩充二叉树,每个外部节点Ki有一个Wi对应,作为该外部节点的权。使得这个扩充二叉树的叶节点带权外部路径长度总和最小: Min( W1 * L1 + W2 * L2 + W3 * L3 + … + Wn * Ln) Wi:每个节点的权值。 Li:根节点到第i个外部叶子节点的距离。 编程计算最小外部路径长度总和。 输入 第一行输入一个整数t,代表测试数据的组数。 对于每组测试数据,第一行输入一个整数n,外部节点的个数。第二行输入n个整数,代表各个外部节点的权值。 2<=N<=100 输出 输出最小外部路径长度总和。 样例输入 2 3 1 2 3 4 1 1 3 5 样例输出 9 17 提示 仅考查huffman树的建立,数据范围小,可以不需要使用堆结构. 不过鼓励使用第一题实现的堆来寻找最小和次小元素。