ハフマンの木
各ノードの重みは、ルートノードのパス長の合計が最小のツリーで乗算されます。最適なバイナリツリー
ハフマンツリーの特性:
a次数1のノードはありません。;
任意葉ノードの左と右のサブツリーは、交換後もハフマンツリーです。葉ノードがnのハフマンツリーは、合計2n-1ノードです
。同じ重みのセット{w1、w2、……、wn} 、ハフマンツリーの異なる構成が存在する
構成ハフマンツリー
最小ヒープ・サイズに変換することによって、ノードの重みバイナリポイントは、各撮影2つのスタック要素が新しいバイナリノードがヒープに戻し所与は、
実行するときサイズ1のマージ、最終結果はハフマンツリーです。
1.ツリーノード
#include <iostream>
#include <string>
using namespace std;
#define MaxNum 64
struct TreeNode{
int Weight = 0;
TreeNode *Left = nullptr;
TreeNode *Right = nullptr;
};
2.ヒープ構造
struct HeapNode{// 堆结构
TreeNode Data[MaxNum]; //data内放着树结构
int Size =0; //初始大小为0
};
3.ヒープ作成機能
HeapNode * CreateHeap(){ //建树——返回指向树根节点的指针
HeapNode *H = new(HeapNode);
H->Data[0].Weight = -1; //哨兵的weight设置为-1
return H; //建堆——一次即可
}
4.ヒープ削除機能
TreeNode *DeleteMin(HeapNode *H){ //返回堆定的指针
int Parent = 0 , Child=0;
TreeNode temp;
TreeNode *MinItem = new(TreeNode); //新建一个minitem
*MinItem = H->Data[1]; //保存堆顶
temp = H->Data[(H->Size)--]; //拿到堆底的对象,并且size-1
for(Parent=1;Parent *2 <= H->Size; Parent=Child)
{
Child= Parent*2;
//Size就是为了作为边界
if(Child!=H->Size && (H->Data[Child].Weight>H->Data[Child+1].Weight))
Child++;
if(temp.Weight<=H->Data[Child].Weight) break;
else H->Data[Parent]=H->Data[Child]; //下沉
}
//break出来说明找到合适位置
H->Data[Parent] = temp; //进行赋值
return MinItem; //返回堆定成员指针
}
5.ヒープ操作を挿入する
void Insert(HeapNode *H, TreeNode *item){ //将一个树成员插入堆中
int i=0;
i= ++(H->Size); //i为当前总容量
//item为指向树成员的指针
for (;item ->Weight<H->Data[i/2].Weight;i/=2) //插入最后,然后上浮
//当要插入的成员小于父节点,上浮
{
H->Data[i]=H->Data[i/2];
}
H->Data[i] = *item; //将item所指成员放入堆中
}
6.ハフマンツリーを構築する
最小のヒープオブジェクトへのポインタを入力します。
TreeNode *Huffman(HeapNode *H){ //把堆变为哈夫曼树
TreeNode *T = nullptr; //初始空指针
int num = H->Size; //一共有num个元素
//进行n-1次合并
for(int i=0;i<num-1;i++)
{
T= new(TreeNode);
T->Left = DeleteMin(H);
T->Right = DeleteMin(H);
T->Weight=T->Left->Weight + T->Right->Weight;
Insert(H,T); //T为指针——insert(H,T)
//要用动态内存创造空间时——用指针
}
T= DeleteMin(H);
return T; //返回指向堆头的指针
//
}
まとめ
ハフマンツリーは最小のヒープから変換され、
バイナリツリーを最適なバイナリツリーにする
ことができます。あいまいさを回避して、最小のコーディングコストでバイナリツリーを構築できます。