哈夫曼树的建立

来源:互联网 发布:分销系统 php 编辑:程序博客网 时间:2024/05/29 17:31

#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}

               * i0, small10,

               * 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;

}

 

 
原创粉丝点击