闲着去逛论坛,看到有人问建huffman树。记得当初学数据结构时我没写过,所以也来试试。不过这个当作业实在是太迟了:)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//*
做huffman用堆排序应该效率最高了吧,不过自己写一个太麻烦,就直接用stl算了:
*/
#include <cstdio>
#include <vector>
#include <algorithm>
![](/Images/OutliningIndicators/None.gif)
template< class Type >
struct node
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
node *left, *right;
int value;
const Type *data;
struct ptrcmp // 仿函数,用于堆排序的比较
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
bool operator () (const node* a, const node* b)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return a->value > b->value; // 最小堆
}
};
};
![](/Images/OutliningIndicators/None.gif)
template< class Type >
node< Type >* buildHuffmanTree(const Type data[], int count)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
typedef node< Type > Node;
// 初始化堆
::std::vector< Node* > heap(count, NULL);
heap.clear();
for(int i= 0; i < count; i++)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Node *n = new Node;
n->left = NULL;
n->right = NULL;
n->data = &data[i];
n->value = data[i]; // 如果Type不能转化到int,则必须重载一个operator int()
heap.push_back(n);
}
::std::make_heap(heap.begin(), heap.end(), Node::ptrcmp());
![](/Images/OutliningIndicators/InBlock.gif)
// 用堆排序找到最小的2个元素,建立它们的父节点
while(heap.size() > 1)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Node *n1, *n2, *t;
::std::pop_heap(heap.begin(), heap.end(), Node::ptrcmp());
n1 = heap.back();
heap.pop_back();
::std::pop_heap(heap.begin(), heap.end(), Node::ptrcmp());
n2 = heap.back();
t = new Node; // 父节点
t->left = n1;
t->right = n2;
t->value = n1->value + n2->value; // 权值为孩子们权的和
![](/Images/OutliningIndicators/InBlock.gif)
// 再把这个父节点放回堆
heap.back() = t;
::std::push_heap(heap.begin(), heap.end(), Node::ptrcmp());
}
return heap.front();
}
![](/Images/OutliningIndicators/None.gif)
template< class Type >
void destoryTree(node< Type >* root)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
if (root->left) destoryTree(root->left);
if (root->right) destoryTree(root->right);
delete root;
}
![](/Images/OutliningIndicators/None.gif)
template< class Type >
void drawTree(node< Type >* root)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
printf("%d",root->value);
if (root->left)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
printf("(");
drawTree(root->left);
printf(",");
}
if (root->right)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
drawTree(root->right);
printf(")");
}
}
![](/Images/OutliningIndicators/None.gif)
// 测试用例
int main()
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
int data[] =
{2,3,4,5,1,2,3,65,8,2,};
node< int > *root = buildHuffmanTree(data, sizeof(data)/sizeof(data[0]));
![](/Images/OutliningIndicators/InBlock.gif)
drawTree(root); // 结果为:95(30(13(6(3,3),7(3(1,2),4)),17(8,9(4(2,2),5))),65)
printf("\n");
![](/Images/OutliningIndicators/InBlock.gif)
destoryTree(root);
return 0;
}
![](/Images/OutliningIndicators/None.gif)