# 构造哈夫曼树

## 最小堆与哈夫曼的结构

typedef struct HuffmanTree * TNode;
typedef struct Heap * MinHeap;
struct HuffmanTree{
int weight;
TNode Left;
TNode Right;
};
struct Heap{
TNode * Data;
int Size;
int MaxSize;
};


## 最小堆的插入与删除操作

### 插入操作

int InsertHeap(MinHeap H, int a)
{
int i = ++H->Size;
for(; H->Data[i/2]->weight > a; i /= 2)
H->Data[i] = H->Data[i/2];
H->Data[i] = (TNode)malloc(sizeof(struct HuffmanTree));
H->Data[i]->weight = a;
H->Data[i]->Left = H->Data[i]->Right = NULL;
return i;
}


### 删除操作

TNode DeleteHeapMin( MinHeap H )
{
int Parent, Child;
TNode MinItem = H->Data[1];
TNode tmp = H->Data[H->Size--];
for(Parent = 1; Parent * 2  <= H->Size; Parent = Child)
{
Child = Parent * 2;
if((Child != H->Size) && (H->Data[Child]->weight > H->Data[Child + 1]->weight))
Child++;
if(tmp->weight <= H->Data[Child]->weight)
break;
else
H->Data[Parent] = H->Data[Child];
}
H->Data[Parent] = tmp;
return MinItem;
}


## 哈夫曼树的构建

TNode Huffman(MinHeap H)
{
while(H->Size > 1)
{
TNode A, B;
A = DeleteHeapMin(H);
B = DeleteHeapMin(H);
int f = InsertHeap(H, A->weight + B->weight);
H->Data[f]->Left = A;
H->Data[f]->Right = B;
}
return H->Data[1];
}


## 计算WSL

int WPL( TNode T, int Depth)
{
if(T->Left == NULL && T->Right == NULL)
return Depth * T->weight;
else
{
int leftWPL = 0, rightWPL = 0;
if(T->Left) leftWPL = WPL(T->Left, Depth + 1);
if(T->Right) rightWPL = WPL(T->Right, Depth + 1);
return rightWPL + leftWPL;
}
}


## 另：判断某组编码是否为最优编码

1. 有最小权值
2. 具有唯一性：只是路径的节点不能表示为某一元素，即每一个代表编码的节点不能有左子树和右子树
3. 不能有度为1的点。

int judge(int N, int f[], int CodeLen)
{
int flag = 1, w = 0;
TNode T = (TNode)malloc(sizeof(struct HuffmanTree));
T->Left = T->Right = NULL;
T->weight = -1;
for(int i = 0; i < N; i++)
{
char c, s[N + 1];
getchar();
scanf("%c %s", &c, s);
int length = strlen(s);
if(length > N) flag = 0;
w += length * f[i];
int j = 0;
TNode tmp = T;
while(s[j] != '\0')
{
if(s[j] == '0')
{
if(!tmp->Left)
{
tmp->Left = (TNode)malloc(sizeof(struct HuffmanTree));
tmp->Left->weight = -1;
tmp->Left->Left = tmp->Left->Right = NULL;
tmp = tmp->Left;
}
else
{
if(tmp->Left->weight != -1) {
flag = 0;
tmp = tmp->Left;
}
else
tmp = tmp->Left;
}
}
else
{
if(!tmp->Right)
{
tmp->Right = (TNode)malloc(sizeof(struct HuffmanTree));
tmp->Right->weight = -1;
tmp->Right->Right = tmp->Right->Left = NULL;
tmp = tmp->Right;
}
else
{
if(tmp->Right->weight != -1) {
//printf("**warning**\n");
flag = 0;
tmp = tmp->Right;
}
else
tmp = tmp->Right;
}
}
j++;
}
tmp->weight = i;
if(tmp->Left != NULL || tmp->Right != NULL)
flag = 0;

}
if(w > CodeLen)
flag = 0;
free(T);
return flag;
}


11-09 1502

04-11 548
05-20 1245
05-12 586
05-20
09-18