哈夫曼树
- 给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
哈夫曼树的生成
- 这里采用最小堆进行生成
- 事先把带权值的结点生成最小堆
- 然后,如下
HuffmanTree Huffman(MinHeap& H)
{
int i;
HuffmanTree T;
int size = H->size;
for (i = 1; i < size; ++i) {
T = new HuffmanTNode;
T->left = nullptr;
T->left = deleteMin(H);
T->right = nullptr;
T->right = deleteMin(H);
T->weight = T->left->weight + T->right->weight;
insertNode(H, T);
}
T = deleteMin(H);
return T;
}
整整齐齐
# include<iostream>
using namespace std;
typedef struct HuffmanTNode {
int weight;
struct HuffmanTNode* left, * right;
}HuffmanTNode,*HuffmanTree;
typedef struct Heap {
HuffmanTree* elements;
int size;
}Heap,*MinHeap;
# define MaxSize 1000
MinHeap initHeap();
void creatHeap(MinHeap& H, int nums[], int len);
void traverseHeap(MinHeap H);
void insertNode(MinHeap& H, HuffmanTree item);
HuffmanTree deleteMin(MinHeap& H);
HuffmanTree Huffman(MinHeap& H);
void PreOrderTraverse(HuffmanTree T);
int main()
{
int tmp[8] = { 3,1,2,7,6,4,9,0 };
MinHeap H = initHeap();
creatHeap(H, tmp, 8);
traverseHeap(H);
HuffmanTree huffmanTree = new HuffmanTNode;
huffmanTree = Huffman(H);
PreOrderTraverse(huffmanTree);
system("pause");
return 0;
}
MinHeap initHeap()
{
MinHeap H = new Heap;
H->elements = new HuffmanTree[MaxSize+1];
H->size = 0;
H->elements[0] = new HuffmanTNode;
H->elements[0]->weight = -1;
return H;
}
void traverseHeap(MinHeap H)
{
cout << "Heap: H" << " Size: " << H->size << endl;
for (int i = 1; i <= H->size; ++i) {
cout << H->elements[i]->weight << " ";
}
cout << endl;
}
void insertNode(MinHeap& H, HuffmanTree item)
{
if (H->size+1 > MaxSize) {
cout << "堆溢出..." << endl;
return;
}
H->size++;
int i = H->size;
if (H->elements[i])H->elements[i] = nullptr;
H->elements[i] = new HuffmanTNode;
for (; H->elements[i / 2]->weight > item->weight; i /= 2) {
H->elements[i] = H->elements[i / 2];
}
H->elements[i] = item;
}
HuffmanTree deleteMin(MinHeap& H)
{
if (H->size == 0) {
cout << "堆为空..." << endl;
return H->elements[1];
}
HuffmanTree MaxVal = H->elements[1];
HuffmanTree temp = H->elements[H->size];
H->size--;
int parent, child;
for (parent = 1; parent * 2 <= H->size; parent = child) {
child = parent * 2;
if (child < H->size) {
if (H->elements[child]->weight > H->elements[child + 1]->weight) {
++child;
}
}
if (temp->weight <= H->elements[child]->weight)break;
else {
H->elements[parent] = H->elements[child];
}
}
H->elements[parent] = temp;
return MaxVal;
}
void creatHeap(MinHeap& H, int nums[], int len)
{
int i;
if (H->size+len > MaxSize) {
cout << "堆溢出..." << endl;
return;
}
H->size += len;
for (i = 0; i < len; ++i) {
H->elements[i + 1] = new HuffmanTNode;
H->elements[i + 1]->weight = nums[i];
H->elements[i + 1]->left = nullptr;
H->elements[i + 1]->right = nullptr;
}
for (i = H->size / 2; i >= 1; --i) {
int parent, child;
for (parent = i; parent * 2 <= H->size; parent = child) {
child = 2 * parent;
if ((child + 1 < H->size) && (H->elements[child]->weight > H->elements[child + 1]->weight)) {
++child;
}
if (H->elements[parent]->weight > H->elements[child]->weight) {
HuffmanTree temp = H->elements[child];
H->elements[child] = H->elements[parent];
H->elements[parent] = temp;
}
}
}
}
HuffmanTree Huffman(MinHeap& H)
{
int i;
HuffmanTree T;
int size = H->size;
for (i = 1; i < size; ++i) {
T = new HuffmanTNode;
T->left = nullptr;
T->left = deleteMin(H);
T->right = nullptr;
T->right = deleteMin(H);
T->weight = T->left->weight + T->right->weight;
insertNode(H, T);
}
T = deleteMin(H);
return T;
}
void PreOrderTraverse(HuffmanTree T)
{
if (T) {
cout << T->weight << " ";
PreOrderTraverse(T->left);
PreOrderTraverse(T->right);
}
}