<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-28  評論-51  文章-10  trackbacks-0
    以前都是在一個文件里寫代碼的,第一次用了這么多文件(4個_!!),哈,很有成就感阿,還熟悉了linux下的編程環(huán)境,gcc,gdb都是很好好強大的東東,記得下次多用用:
    有不足之處望各位高手指正阿!!!
    huffman.h
     1 /*最小堆操作方法get the data input*/
     2 
     3 //#define MAXSIZE  100
     4 #define DEFAULTSIZE 50
     5 /*最小堆的節(jié)點結(jié)構(gòu)*/
     6 struct hnode
     7 {
     8     char ch;
     9     int index; //索引對應(yīng)于haffman數(shù)組的下標    
    10     int freq;   //對該字段建立最小堆
    11 };
    12 typedef struct hnode *PHHead;
    13 typedef struct hnode HNode;
    14 
    15 
    16 int getdata(PHHead );
    17 
    18 //make the data into min heap structure
    19 void makeMinheap(PHHead , int);
    20 
    21 int IsFull();
    22 int IsEmpty();
    23 void  MoveUP(HNode *);
    24 void MoveDown(HNode *);
    25 int Insert(PHHead , HNode );
    26 HNode DeleteMin(PHHead );
    27 
    28 
    29 
    30 
    31 //哈夫漫操作方法func for construaction of HUFFMAN tree
    32 /*this is a struct for the huffmancode when record*/
    33 typedef char **HuffmanCode;
    34 
    35 
    36 
    37 /*haffman struct*/
    38 typedef struct HuffmanNode{
    39     int freq;
    40     char ch;
    41     int parent, lchild,rchild;
    42 } HTNode, *HuffmanTree;
    43 void  HuffmanCoding(HuffmanTree HT, HuffmanCode HC,  PHHead, int);    //PHHead is a point for input, int is number of element

    Minheap.c最小堆實現(xiàn)
      1 #include <stdio.h>
      2 #include "huffman.h"
      3 
      4 
      5 
      6 HNode heapData[DEFAULTSIZE+1]; //第一個節(jié)點不用
      7 int currentSize = 0;//記錄當前堆的元素個數(shù),currentSize位置當前數(shù)據(jù)的最后一個位置的下標
      8 int totalNum = 0;//輸入的數(shù)據(jù)個數(shù)
      9 
     10 int getdata(PHHead data) //從控制臺獲得輸入數(shù)據(jù),存入最小堆數(shù)組
     11 {
     12     char c = 0//the char
     13     int freq = 0;
     14     scanf("%c %d"&c, &freq);
     15     while(c!='0' && freq != 0)
     16     {
     17         if(currentSize < DEFAULTSIZE)
     18         {
     19             currentSize++;//增加當前大小
     20             heapData[currentSize].ch = c;
     21             heapData[currentSize].freq = freq;
     22             heapData[currentSize].index = currentSize;//放入輸入數(shù)據(jù)的先后索引
     23 
     24             getchar();  //去除輸入的回車等其他無效字符
     25             scanf("%c %d"&c, &freq);
     26         }
     27         else
     28         {
     29             fprintf(stderr, "too many input!!"); //提示:輸入數(shù)據(jù)太多了
     30             return 0;
     31         }
     32     /*    else//if input data number greater than defaultsize, then malloc more
     33         {
     34             
     35         }
     36         */
     37     }
     38     totalNum = currentSize;
     39 }
     40 //對輸入的數(shù)據(jù)形成最小堆,從 元素個數(shù)/2的首個非葉子節(jié)點,迭代構(gòu)建
     41 void makeMinheap(PHHead data, int currentSize) //這里的currentSize不影響全局的該變量
     42 {
     43         HNode tempNode;
     44 
     45         int i = 0;
     46         int j= 0;
     47         int tempi = 0;
     48         for(i = currentSize/2; i>0; i--)  //i表示循環(huán)個數(shù)
     49         {
     50             tempi = i; //單次循環(huán)變量
     51             for(j= 2*tempi; j<=currentSize; j*=2//假設(shè)除本節(jié)點外的子樹已是最小堆,考慮本節(jié)點后,重新形成最小堆
     52             {
     53                 if( j<currentSize && data[j].freq > data[j+1].freq) j++;//找出i節(jié)點兩個子節(jié)點的較小者記為j
     54                 if(data[tempi].freq > data[j].freq)
     55                     {
     56                         tempNode.ch = data[tempi].ch;
     57                         tempNode.freq = data[tempi].freq;
     58                         tempNode.index =  data[tempi].index;
     59                         
     60                         data[tempi].ch = data[j].ch;
     61                         data[tempi].freq = data[j].freq;    
     62                         data[tempi].index = data[j].index;
     63 
     64                         data[j].ch =tempNode.ch;
     65                         data[j].freq = tempNode.freq;    
     66                         data[j].index =tempNode.index;    //交換i,j節(jié)點的數(shù)據(jù)
     67                         
     68                         tempi = j; //把還下來的數(shù)據(jù)一直放到合適的位置
     69                                 
     70                     }
     71                 else break;
     72             }
     73         }
     74 }
     75 
     76 int IsFull()
     77 {
     78     if(currentSize >= DEFAULTSIZE)
     79         return 1;
     80     else
     81         return 0;
     82 }
     83 int IsEmpty()
     84 {
     85     if(currentSize == 0)
     86         return 1;
     87     else
     88         return 0;
     89 }
     90 //把已經(jīng)插入并放在最尾端的一個元素,重構(gòu)最小堆
     91 void  MoveUP(HNode * heap)
     92 {
     93     HNode temp;
     94     int i = currentSize;
     95             for(; i >=1;i/=2)
     96             {
     97                 if(heap[i].freq < heap[i/2].freq)
     98                 {
     99                     temp.ch = heap[i/2].ch;
    100                     temp.freq = heap[i/2].freq;            
    101                     temp.index = heap[i/2].index;
    102                             
    103                      heap[i/2].ch = heap[i].ch ;                    
    104                      heap[i/2].freq = heap[i].freq ;    
    105                      heap[i/2].index = heap[i/2].index;
    106                      
    107                     heap[i].ch =temp.ch;
    108                     heap[i].freq = temp.freq; 
    109                     heap[i].index = temp.index;
    110                 }
    111                 else
    112                 break;
    113                     
    114             }
    115     
    116 }
    117 //當取走最小元素后,把最小堆的最后一個元素放在該位置,重構(gòu)最小堆
    118 void MoveDown(HNode *heap)
    119 {
    120     HNode temp;
    121     int i=1 ;
    122     int j=0;
    123     for(j=2*i; j <= currentSize; j*=2)
    124     {
    125         if(j<currentSize && heap[j].freq> heap[j+1].freq) j++;
    126         if(heap[i].freq < heap[j].freq) break;
    127         temp.ch = heap[j].ch;
    128         temp.freq = heap[j].freq;
    129         temp.index = heap[j].index;
    130         
    131         heap[j].ch = heap[i].ch;
    132         heap[j].freq = heap[i].freq;
    133         heap[j].index = heap[i].freq;
    134         
    135         heap[i].ch = temp.ch;
    136         heap[i].freq = temp.freq;
    137         heap[i].index = temp.index;
    138         
    139         i = j;
    140     }
    141 }
    142 //完成插入新元素,并重構(gòu)最小堆
    143 int Insert(PHHead heap , HNode node)
    144 {
    145     heap[currentSize+1].ch = node.ch;
    146     heap[currentSize+1].freq = node.freq;
    147     heap[currentSize+1].index = node.index;
    148     currentSize++;
    149     MoveUP(heap);    
    150     
    151 }
    152 //完成刪除最小元素,并重構(gòu)最小堆
    153 HNode DeleteMin(PHHead heap )
    154 {
    155     HNode node;
    156     node.ch = heap[1].ch;
    157     node.freq = heap[1].freq;
    158     node.index = heap[1].index;
    159     
    160     heap[1].ch = heap[currentSize].ch;
    161     heap[1].freq = heap[currentSize].freq;    
    162     heap[1].index = heap[currentSize].index;    
    163     
    164     currentSize--;
    165     MoveDown(heap);
    166     
    167     return node;
    168 }
    169 

    haffman.c 哈夫曼實現(xiàn)
     1 #include <stdio.h>
     2 #include<stdlib.h>
     3 #include <string.h>
     4 #include "huffman.h"
     5 extern HNode heapData[DEFAULTSIZE]; 
     6 extern int currentSize;
     7 extern int totalNum;
     8 int currentSizeTree = 0;//樹結(jié)構(gòu)的當前長度
     9 HuffmanCode HC;
    10 
    11 /*對n個元素,構(gòu)建哈夫曼樹HT,輸出每個元素的哈夫曼編碼,在操作過程中,取最小權(quán)重元素的操作由最小堆完成*/
    12 void  HuffmanCoding(HuffmanTree HT, HuffmanCode HCtemp,  PHHead heap , int n)
    13 {
    14      HNode hnode1; //從最小堆里面取出的兩個元素
    15       HNode hnode2;
    16     int m = n+1// the index number that merged nodes starts
    17     if(n <= 1return;
    18        
    19        while(!IsEmpty())
    20        {
    21 
    22            //從最小堆中取出兩個最小元素,并保存到huffman樹結(jié)構(gòu),并建立關(guān)聯(lián)
    23            if(currentSize <=1)
    24            {
    25                 break;//直接返回,輸入只有一個元素,一開始用return,錯誤阿!!
    26            }
    27           else  //如果最小堆里有>=2個元素
    28            {
    29           
    30                hnode1 =  DeleteMin(heapData );
    31                hnode2=  DeleteMin(heapData );
    32             int i = hnode1.index;
    33             int j = hnode2.index;
    34 
    35             HT[i]. parent = currentSizeTree+1//建立新節(jié)點
    36             HT[j].parent = currentSizeTree+1;
    37             currentSizeTree++//樹結(jié)構(gòu)元素個數(shù)增加一
    38         
    39             HT[currentSizeTree].lchild = i;
    40             HT[currentSizeTree].rchild = j;
    41             HT[currentSizeTree].parent =0;//把默認父結(jié)點設(shè)為0,便于編碼判斷
    42             
    43             HT[currentSizeTree].freq =  hnode1.freq + hnode2.freq;
    44             //創(chuàng)建最小堆節(jié)點(兩個最小元素的合并),并插入,重構(gòu)最小堆
    45             HNode hnode;
    46             hnode.index =currentSizeTree;
    47             hnode.freq =HT[currentSizeTree].freq;
    48             Insert(heapData, hnode);
    49         }
    50 
    51     }        
    52     
    53             //以下求從葉子到根的huffman編碼
    54             HCtemp = (HuffmanCode)malloc((totalNum+1)*sizeof(char*));
    55             int length =totalNum;//編碼的最大長度,應(yīng)該為輸入構(gòu)建樹后,數(shù)目減去1,但'\0' +1
    56             char *cd = (char *)malloc(length*sizeof(char)); 
    57             cd[length-1= '\0';
    58             int i = 0;
    59             int c;
    60             int start;//編碼開始標號
    61             int f; //父結(jié)點下標
    62             for(i = 1; i <=totalNum;++i)
    63             {
    64                 start = length-1;//編碼結(jié)束符
    65                 for(c=i, f=HT[i].parent; f!=0; c=f,f=HT[f].parent)
    66                       if(HT[f].lchild == c) cd[--start] = '0';
    67                       else cd[--start] = '1';
    68 
    69 
    70 
    71                 HCtemp[i] = (char *)malloc(length*sizeof(char)); //加上'\0' +1
    72                 strcpy(HCtemp[i], &cd[start]);
    73                 
    74             }
    75             HC = HCtemp;   //c語言沒有引用類型,所以最后要把指針傳回去阿!!!
    76             free(cd);       
    77 }

    最后main.c
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include "huffman.h"
     4 extern HNode heapData[DEFAULTSIZE+1];
     5 extern int currentSize;//堆的當前長度
     6 extern int currentSizeTree;//樹的當前長度
     7 extern int totalNum;//輸入的總個數(shù)
     8 extern     HuffmanCode HC;//哈夫曼編碼
     9 
    10 void printCode(HuffmanCode HC,int n);
    11 void dataCpy(HuffmanTree, HNode[]); //從堆結(jié)構(gòu)的輸入數(shù)據(jù)中cpy數(shù)據(jù)到樹結(jié)構(gòu)中
    12 void printOutHeap(HNode* heapData, int size);//測試用:把推結(jié)構(gòu)的數(shù)據(jù)打印出來
    13 void printOutTree(HuffmanTree treeData, int size);//測試用:把樹結(jié)構(gòu)的數(shù)據(jù)打印出來
    14 int  main()
    15 {
    16     currentSizeTree = 0;//樹長度初始化為0
    17 
    18     int chNum;    
    19     getdata(heapData); // 為對結(jié)構(gòu)輸入數(shù)據(jù)
    20 
    21     int lengthOfFinalTree = currentSize *2-1;//
    22     HuffmanTree HT = (HuffmanTree)malloc(sizeof(HTNode)*currentSize *2 ); //創(chuàng)建數(shù)組形式的樹,個數(shù)為樹節(jié)點的個數(shù)2*n-1,首節(jié)點不用+1
    23     dataCpy(HT,heapData);//把數(shù)據(jù)復(fù)制到樹結(jié)構(gòu)中
    24     
    25     chNum = currentSize;
    26     makeMinheap(heapData, chNum);
    27     
    28     /*HNode a;
    29     a.ch = 'k';
    30     a.freq = 3;
    31      Insert(heapData , a );
    32      makeMinheap(heapData,currentSize);*/
    33      
    34 //      DeleteMin(heapData);
    35 
    36     HuffmanCoding(HT, HC,  heapData, chNum);
    37 //    printOutHeap(heapData, currentSize);
    38     printOutTree(HT, lengthOfFinalTree);
    39     printCode(HC,totalNum);
    40     return 0;
    41 }
    42 
    43 void printCode(HuffmanCode HC,int n)//n是元素個數(shù)
    44 {
    45     int i;
    46     char* t;
    47     char c;
    48     for(i =1; i <= n; i++)
    49     {
    50         t = HC[i];
    51         for(;  (c=*t) != '\0'; t++)
    52         {
    53             printf("%c", c);
    54         }
    55         printf("\n");
    56     }
    57 }
    58 void dataCpy(HuffmanTree t, HNode s[])//從堆結(jié)構(gòu)的輸入數(shù)據(jù)中cpy數(shù)據(jù)到樹結(jié)構(gòu)中
    59 {
    60     int i = currentSize+1;//數(shù)據(jù)輸入的規(guī)模
    61     while(--i>0)
    62     {
    63         t[i].freq = s[i].freq;
    64         t[i].ch = s[i].ch;
    65         currentSizeTree ++;//更新樹結(jié)構(gòu)的長度
    66         
    67     }
    68 }
    69 
    70 //打印出推結(jié)構(gòu)的數(shù)據(jù),測試用
    71 void printOutHeap(HNode* heapData, int size)
    72 {
    73     int i = 1 ;
    74     for(;i<=size; i++)
    75     {
    76         printf("%d %c\n", i, heapData[i].ch);
    77     }
    78     printf("\nthis is the end!! ");
    79 }
    80 //打印出樹結(jié)構(gòu)的數(shù)據(jù),測試用
    81 void printOutTree(HuffmanTree treeData, int size)
    82 {
    83     int i;
    84     for(i=1; i<=size;i++)
    85     {
    86         //printf("%d %c\n",i, treeData[i].ch);
    87         printf("%d: %d\n",i, treeData[i].freq);
    88     }
    89 }


    gcc下用如下命令
    gcc -g -o main huffman.h Minheap.c huffman.c main.c
    debug with
    gdb main

    感覺程序有點寫的太冗長了,不知道哪里可以精簡下?






    posted on 2008-03-28 23:29 fullfocus 閱讀(2943) 評論(9)  編輯  收藏 所屬分類: 算法

    評論:
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2008-03-29 15:28 | ZelluX
    函數(shù)命名方法不統(tǒng)一阿
      回復(fù)  更多評論
      
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2008-03-29 15:55 | fullfocus
    @ZelluX
    你好,一般在c程序里面,函數(shù)命名方式是什么樣的呢?
    第一個單詞小寫后面每個單詞首字母大寫嗎? 懇請指教!  回復(fù)  更多評論
      
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2008-03-29 18:31 | raof01
    同學(xué),你這練習(xí)——全局變量滿天飛  回復(fù)  更多評論
      
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2008-03-29 18:33 | raof01
    算法不錯  回復(fù)  更多評論
      
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2008-03-29 20:18 | fullfocus
    @raof01
    因為文件之間要傳遞變量,沒辦法只能設(shè)這么多全局的了,您有其他建議嗎?謝謝:)  回復(fù)  更多評論
      
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2008-03-29 20:53 | ZelluX
    @fullfocus
    怎么命名都可以,關(guān)鍵是要統(tǒng)一。  回復(fù)  更多評論
      
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2008-03-29 22:23 | raof01
    @fullfocus
    可以說,這個問題更多的是與封裝(C語言提供了某種程度的封裝)相關(guān)。也許是java對你的影響,因此你對C/C++將聲明和定義分開的方式還不是很習(xí)慣。要消除全局變量,可以將其封裝到struct/class中,就像你在java中做的一樣。如:
    // heap.h
    class HeapData; //前向聲明
    class Heap
    {
    public:
    // Public methods go here
    private:
    HeapData * m_Data;
    };
    有了這個聲明,就可以在main()中這樣使用:
    Heap aHeap;
    // ...
    也許對于習(xí)慣于java思維的人來說,這樣很難理解。不過你已經(jīng)注意到了C/C++的聲明與定義分開。思考一下,到底為什么要這么做——相信很快你就會知道如何eliminate這些global variables。  回復(fù)  更多評論
      
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2008-04-02 00:12 | billjeff
    嘿嘿,作為練習(xí)是值得肯定的。練習(xí)了多文件組織、GDB、算法學(xué)習(xí)和實現(xiàn)。建議再試試寫個Makefile、做成一個lib。想想用C寫鏈表是怎么寫的,節(jié)點用struct,相關(guān)的變量封裝到struct,你這兒也可以多用struct封裝,然后相關(guān)函數(shù)只需傳入一些結(jié)構(gòu)即可,減少全局變量。我也習(xí)慣C++思維,看到最小堆就會想到用模板來做~不過滿足需要就行。  回復(fù)  更多評論
      
    # re: 第一次寫這么多代碼_!!--純c哈夫曼代碼實現(xiàn)(用了最小堆) 2012-03-21 04:31 | kenan
    1.結(jié)構(gòu)體交換數(shù)據(jù)不用把所有成員都拿出來交換
    2.沒有考慮到頻數(shù)相同的情況

      回復(fù)  更多評論
      
    主站蜘蛛池模板: 午夜免费1000部| 免费在线观看污网站| 亚洲av成本人无码网站| 亚洲A丁香五香天堂网| a毛片在线免费观看| 亚洲婷婷在线视频| 人人狠狠综合久久亚洲高清| 国产精品视频白浆免费视频| 亚洲午夜一区二区三区| 亚洲一区二区三区在线视频| 亚洲精品国产免费| 美女黄频免费网站| 亚洲高清视频在线观看| 男女啪啪永久免费观看网站| 最近中文字幕免费大全| 亚洲欧美日韩自偷自拍| 久久精品夜色国产亚洲av| 日韩免费高清一级毛片在线| 黄网站免费在线观看| 亚洲人成未满十八禁网站| 亚洲AV日韩AV高潮无码专区| 日本一道在线日本一道高清不卡免费| 久操视频免费观看| 色屁屁www影院免费观看视频| 亚洲日产2021三区在线| 亚洲综合无码精品一区二区三区| 成人影片麻豆国产影片免费观看 | 亚洲av无码一区二区三区天堂| 亚洲春色在线视频| 免费看国产一级特黄aa大片| 国产精彩免费视频| a级特黄毛片免费观看| 无码一区二区三区亚洲人妻| 亚洲男人天堂av| 国产亚洲日韩一区二区三区| 麻豆成人精品国产免费| 动漫黄网站免费永久在线观看| 国产免费AV片在线观看| yellow视频免费看| 边摸边吃奶边做爽免费视频99| 亚洲一区二区三区播放在线|