C語言數據結構創建哈夫曼樹-Huffman coding

/*
*創建哈弗曼樹
*創建樹
*每次遍歷最小的兩個節點
*譯碼
*遍歷樹(解碼的過程)
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define n  4//樹的葉子節點數
#define m  (2*n-1)//樹的節點總數
#define MAXVALUE 1000 //權重最大值
typedef struct htreetype
{
    int weight;//權重
    int parent;//雙親節點
    int Rchild;
    int Lchild;//左右孩子節點
    char name[5];//節點名稱

}HtreeType;//樹節點的結構體
typedef struct hcodetype
{
    char bit[n];//用於存放編碼的數組
     char name[5];//儲存節點的名稱
     int start;//編碼開始的下標

}HcodeType;//編碼節點的結構體
void select_htree(HtreeType tree[],int position,int *node1,int *node2);//選擇最小的兩個
void htree_code(HtreeType tree[],HcodeType code[]);//譯碼的過程
void creat_htree(HtreeType tree[]);//哈夫曼樹的創建
void show_htree(HcodeType code[] );//輸出
int main()
{
    HtreeType tree[m];
    HcodeType code[n];
    htree_code(tree,code);
    show_htree(code);
    return 0;


}
void creat_htree(HtreeType tree[])//哈夫曼樹的創建
{
    /*
      *初始化樹的節點
      *給樹的葉子節點賦值
      *利用選擇函數進行分支節點的創建
    */
    int node1,node2;
    char name[5];//臨時字符串
    int now_weight;//臨時變量
    int i,j,k;
    node1=node2=0;
    for(i=0;i<m;i++)
    {
        tree[i].weight=0;
        tree[i].Rchild=-1;
        tree[i].Lchild=-1;
        tree[i].parent=-1;
    }
    printf("一共有%d個葉子節點\n",n);
    for(j=0;j<n;j++)
    {
          printf("請輸入節點的數據:");
          scanf("%s",name);
          printf("請輸入葉子節點的權重:");
          scanf("%d",&now_weight);
           tree[j].weight=now_weight;
            strcpy(tree[j].name,name);


    }
    for(k=n;k<m;k++)
    {
        select_htree(tree,k,&node1,&node2);
        tree[node1].parent=k;
        tree[node2].parent=k;
        tree[k].Rchild=node2;
        tree[k].Lchild=node1;
        tree[k].weight=tree[node1].weight+tree[node2].weight;
    }
}
void select_htree(HtreeType tree[],int position,int *node1,int *node2)
//選擇最小的兩個
{
    /*
    *以position爲起始點進行尋找最小的兩個節點的下標
    *每次調用之後返回
    */
    int i;
    int min1,min2;
    min1=min2=MAXVALUE;
     *node1=*node2=0;
     for(i=0;i<position;i++)
     {
         if(tree[i].parent==-1&&tree[i].weight<min1)
         {
             min2=min1;
             min1=tree[i].weight;
             *node2=*node1;
             *node1=i;

         }
         else if(tree[i].parent==-1&&tree[i].weight<min2)
         {
             min2=tree[i].weight;
              *node2=i;
         }
     }
}
void htree_code(HtreeType tree[],HcodeType code[] )//譯碼的過程
{
    HcodeType cd;//臨時儲存節點的編碼
    int i;//循環變量
    creat_htree(tree);
    int parent_position,now_position;
    for(i=0;i<n;i++)
       {
           cd.start=n;
           strcpy(cd.name,tree[i].name);
           now_position=i;
           parent_position=tree[i].parent;
           while(parent_position!=-1)//從下往上遍歷指點根節點結束
           {
               cd.start--;//作爲數組的循環下標
               if(tree[parent_position].Lchild==now_position)
                   cd.bit[cd.start]='0';
                   else
                   {
                       cd.bit[cd.start]='1';
                   }
                   now_position=parent_position;
                 parent_position=tree[now_position].parent;
           }
           code[i]=cd;//傳遞編碼到code數組去
        }
}
void show_htree(HcodeType code[] )//輸出
{
     int i,j;
     for(i=0;i<n;i++)
     {
            printf("%s     ",code[i].name);
           for(j=code[i].start;j<n;j++)
            printf("%c",code[i].bit[j]);
             printf("\n");
    }

}





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