赫夫曼樹和赫夫曼編碼 (純C)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
構造赫夫曼樹
        n個葉子  2n+1個結點
        一組帶權值的葉子
        找權值最小的兩個葉子  ( 尋找最小兩個權值的葉子
                        生成新結點
                        其權值爲兩葉子權值之和
                        兩葉子的父節點改爲新生成結點
                        新生成結點 父節點爲 0 。 左右孩子結點是兩葉子 (規定權值小的在左  大的在右

生成赫夫曼編碼
        二維數組
        for循環
                從葉子到根 。n-1 = '\0'  start  = n - 1  start--
                n - 1 組二進制編碼 長度爲 n-start
*/

//-------------------赫夫曼樹和赫夫曼編碼的存儲表示----------------------
typedef int ElemType ;

typedef struct HTnode{
        ElemType data ;
        int weight ;
        int parent ;
        int Lchild , Rchild ;
}HTNode , *HuffmanTree ; //動態分配數組存儲赫夫曼樹

typedef char * * Huffmancode ; //動態分配數組存儲赫夫曼樹

void CreateHuffmanTree(HuffmanTree * T , int * w , int n)
{
        int i ;
        int j ;
        int min1 ;
        int min2 ;
        *T = (HuffmanTree)malloc(sizeof(HTNode) * (n+1) ) ;
        for(i = 1 ; i <= n ; i++)
        {
                (*T)[i].data = i ;
                (*T)[i].weight = w[i-1] ;
                (*T)[i].parent = 0 ;
                (*T)[i].Lchild = 0 ;
                (*T)[i].Rchild = 0 ;

        }
        for( i = n + 1 ; i <= 2*n-1 ; i++)
        {
                for( j = 1 ; j < i ; j++)
                {
                         if((*T)[j].parent == 0 )
                                {
                                        min1 =j ;
                                        break ;
                                }
                }
                for( j = 1 ; j < i ; j++)
                {
                        if((*T)[j].parent != 0 )continue ;
                        if( (*T)[j].weight < (*T)[min1].weight)
                        {
                                min1 = j ;
                        }
                }
                for(j =  1 ; j < i ; j++)
                {
                        if((*T)[j].parent == 0 && j != min1)
                                {
                                        min2 = j ;
                                        break;
                                }
                }
                for( j = 1 ; j < i ; j++)
                {
                        if((*T)[j].parent != 0 )continue ;
                        if( (*T)[j].weight < (*T)[min2].weight && j != min1)
                        {
                                min2 = j ;
                        }
                }
                T[i]= (HuffmanTree)malloc(sizeof(HTNode));
                (*T)[i].data = i ;
                (*T)[i].weight = (*T)[min1].weight + (*T)[min2].weight ;
                (*T)[i].parent = 0 ;
                (*T)[i].Lchild = (*T)[min1].data ;
                (*T)[i].Rchild = (*T)[min2].data ;
                (*T)[min1].parent = (*T)[i].data ;
                (*T)[min2].parent = (*T)[i].data ;
        }
}
void CreateHuffmanCode(HuffmanTree HT ,  Huffmancode *HC , int n)
{
        int i ;
        int start ;
        int c ;
        int f ;
        char *cd ;
        *HC = malloc(sizeof(char*) * (n+1) ) ;
        cd =  malloc(sizeof(char) * n) ;
        cd[n-1] = '\0' ;
        for(i = 1 ; i <= n ; i++ )
        {
                start = n -1 ;
                for( c = i , f = HT[i].parent ;  f != 0 ; c = f , f = HT[f].parent)
                if(c == HT[f].Lchild)
                        cd[--start] = '0' ;
                else
                        cd[--start] = '1' ;
                (*HC)[i] = malloc(sizeof(char*)*(n-start) ) ;
                strcpy((*HC)[i] , &cd[start]) ;
                printf("\nHT[%d]  node's Huffman code is : %s" , i , (*HC)[i]) ;
        }
        printf("\n");
        free(cd) ;
}
void print(HuffmanTree T  , int n)
{
        int i = 0 ;
        while( i ++<2*n-1)
        {
                printf("%d %d %d %d %d\n" , T[i].data , T[i].weight , T[i].parent , T[i].Lchild , T[i].Rchild  ) ;
        }

}

int main()
{
        HuffmanTree HT ;
        Huffmancode HC ;
        int *w ;
        int n ;
        int i = 0 ;
        printf("有多少葉子:");
        scanf("%d" , &n) ;
        w = (int *)malloc(sizeof(int) *n) ;
        printf("\n請輸入權值:");
        while( i < n )
        {
                scanf("%d" , &w[i] ) ;
                i++;
        }
        CreateHuffmanTree(&HT,w , n) ;
        print(HT , n) ;
        CreateHuffmanCode( HT ,   &HC ,  n) ;

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章