#include <stdio.h>
#include <stdlib.h>
#define MAX 32767
#define N 4
#define M 2*N-1
typedef struct tagNode
{
int parent;
int weight;
int lChild;
int rChild;
} Node;
Node *huffmanTree;
// ---------------------------------------------------------------------
/* 初始化huffmanTree, */
void initHFTree(int *w)
{
int i;
for(i=0; i<M; i++) {
if(i<N)
huffmanTree[i].weight = w[i];
else
huffmanTree[i].weight = 0;
huffmanTree[i].parent = -1;
huffmanTree[i].lChild = -1;
huffmanTree[i].rChild = -1;
}
}
/* 从容器内查找出最小的两个值 */
void selectMin(Node *T, int k, int *p1, int *p2)
{
if(k < 2) return ;
int small1 = MAX;
int small2 = MAX;
int i;
for(i=0; i<k; i++) {
if(T[i].parent == -1) { // -1标志这个节点没有双亲, 也就是没有被合并过
if(T[i].weight <= small1) { // ------------- 1
/*
* 保证small1是最小的, 当small1遇到比自己还小的值时, 就把自己扔给small2,
* 如此循环下去, small1总是最小的, small2总是倒数第2小的.
* 意外的情况是small1刚一进入循环时就是最小, 则一直无法查找到比自己还小的
* 值, 这时small2接到的就是small1扔过来的MAX. BUG就出现了.
*
* 比如我有一个weight={0, 1, 2, 3}
* 当i为0时, small1为0,
* 在2处会把small2也设为0
* p1,p2都指向了0, 无法找到最小的2个值, 只找到了最小的一个值.
*/
small2 = small1;
*p2 = *p1;
//small1 = T[i].weight;
*p1 = i;
} else if(T[i].weight < small2) { // --------------- 2
small2 = T[i].weight;
*p2 = i;
}
}
}
if (*p1 > *p2) {
int t = *p1;
*p1 = *p2;
*p2 = t;
}
}
/* 从容器内查找出最小的两个值 */
void selectMin2(Node *T, int k, int *p1, int *p2)
{
int small1 = MAX;
int small2 = MAX;
int i;
for(i=0; i<k; i++) { // 第一次遍历查找最小值
if(T[i].parent == -1) {
/*
* -1标志这个节点没有双亲, 也就是没有被合并过
*/
if(T[i].weight <= small1) {
small1 = T[i].weight;
*p1 = i;
}
}
}
for(i=0; i<k; i++) { // 第二次遍历查找次最小值
if(T[i].parent==-1 && *p1!=i ) {
/*
* -1标志这个节点没有双亲, 也就是没有被合并过
* *p1!=i限定要跳过最小值, 也就是第一次循环中查找到的值.
*/
if(T[i].weight <= small2) {
small2 = T[i].weight;
*p2 = i;
}
}
}
}
void createHFTree()
{
int i;
int *p1, *p2;
p1 = (int *)calloc(1, sizeof(int));
p2 = (int *)calloc(1, sizeof(int));
for(i=N; i<M; i++) {
selectMin2(huffmanTree, i, p1, p2);
huffmanTree[*p1].parent = huffmanTree[*p2].parent = i;
huffmanTree[i].weight = huffmanTree[*p1].weight + huffmanTree[*p2].weight;
huffmanTree[i].lChild = *p1;
huffmanTree[i].rChild = *p2;
huffmanTree[i].parent = -1;
}
free( p1 );
free( p2 );
}
int main(int argc, char *argv[])
{
printf("Hello, world/n");
int i;
int *weight = NULL;
weight = (int *)calloc(N, sizeof(int));
for(i=0; i<N; i++) { // input
printf("%d please input your weight---->", i);
scanf("%d", &weight[i]);
}
huffmanTree = (Node *)calloc(M, sizeof(Node));
initHFTree( weight ); // initialize the huffman tree.
createHFTree(); // create huffman tree
for(i=0; i<M; i++) {
printf("%d , %d/n", i, huffmanTree[i].weight);
}
system("pause");
return 0;
}