- 最後登錄
- 2024-2-3
- 在線時間
- 77 小時
- 註冊時間
- 2009-5-25
- 閱讀權限
- 30
- 精華
- 0
- UID
- 6440807
- 帖子
- 153
- 積分
- 1615 點
- 潛水值
- 13857 米
| 小弟提供一個方法
我是把每一個Huffman碼全部算出來
然後再去算結果- #include <iostream>
- using namespace std;
- struct Huffman {
- char ch ;
- int times ;
- char *code ;
- bool isLeaf ;
- Huffman *r , *l , *next ;
- } ;
- void InsertionSort ( Huffman *x , int size ) ;
- Huffman * MergerCode ( Huffman *x , int size ) {
- if ( size == 1 ) //如果size = 1的時候,代表整棵樹已經建立完成
- return x ; //回傳x
- InsertionSort(x , size ) ; //把x根據times & ch 排序
-
-
- Huffman tmp ;
- tmp.ch = NULL ;
- tmp.times = x[0].times + x[1].times ; //把最小的前兩個code合併成一個code
- tmp.l = &x[0] ;
- tmp.r = &x[1] ;
- tmp.isLeaf = false ;
- Huffman *t = new Huffman[size - 1] ; //建一個比input還要小一個的空間
- int i ;
- for ( i = 2 ; i < size ; i++ ) //把後面的code放入t
- t[i - 2 ] = x[i] ;
- t[i-2] = tmp ; //最後把合併的code放入t的最後一個
- return MergerCode ( t , size - 1) ; //遞迴呼叫自己的函式
- }
- class SimpleSearch {
- private:
- Huffman *sQueue , *ptr ;
- bool SelectNode () {
- if ( ! this->sQueue->isLeaf ){ //如果現在指向的元素不是樹葉
- Huffman *t = this->sQueue ; //point to current vQueue
-
- while ( t->next != NULL ) //找到sQueue的最後一個指標
- t = t->next ;
- int i = 0 ;
- char *buffer = new char [50] ;
- for ( ; i < (int)strlen(this->sQueue->code) ; i++ ) //把目前的節點的code記錄到buffer裡面
- buffer[i] = this->sQueue->code[i] ;
- buffer[i] = '\0' ;
- t->next = this->sQueue->l ; //把目前的節點的左子樹加入sQueue最後
- t->next->code = new char [50] ;
- for ( i = 0 ; i < (int) strlen ( buffer ) ; i++ )
- t->next->code [i] = buffer[i] ;
- t->next->code[i++] = '0' ;
- t->next->code[i] = '\0' ;
- t = t->next ;
- t->next = this->sQueue->r ; //把目前的節點的右子樹加入sQueue最後
- t->next->code = new char [50] ;
- for( i = 0 ; i < (int) strlen( buffer ) ; i++ )
- t->next->code[i] = buffer[i] ;
- t->next->code[i++] = '1' ;
- t->next->code[i] = '\0' ;
-
- t->next->next = NULL ;
- delete []buffer ;
- }
- this->sQueue = this->sQueue->next ; //指向下一個code
- if ( this->sQueue == NULL )
- return false ;
- return true ;
- } ;
- public:
- Huffman *first ;
- SimpleSearch(Huffman *root ) {
- this->first = new Huffman() ;
- this->ptr = first ;
- this->sQueue = root ;
- this->sQueue->code = new char [50] ;
- this->sQueue->code[0] = '\0' ;
- this->sQueue->next = NULL ;
- } ;
- void BFS( ) {
- if ( !SelectNode( ) ) {
- return ;
- } else {
- if ( this->sQueue->ch != NULL ) { //如果目前的.ch 不是NULL
- ptr->next = this->sQueue ; //把目前的節點加入ptr後面
- ptr = ptr->next ;
- }
- BFS() ;
- }
- } ;
- } ;
- void InsertionSort ( Huffman *x , int size ) {
- for ( int i = 1 ; i < size ; i++ ) {
- int j = i ;
- while ( j > 0 ) {
- if ( x[j].times < x[j-1].times )
- swap(x[j] , x[j-1] ) ;
- else if ( x[j].times == x[j-1].times ) {
- if ( x[j].ch < x[j-1].ch )
- swap(x[j] , x[j-1] ) ;
- }
- j -= 1;
- }
- }
- }
- int main() {
- char input[80] ;
- cin.getline(input , 80 , '\n') ;
- cout << "input-> " << input << endl ;
- Huffman Codes[80] ;
- int i = 0 , ammount = 0 ;
-
- //把輸入字元做統計
- while ( input[i] != '\0' ) {
- bool flag = false ;
- for ( int j = 0 ; j < ammount ; j++ ){
- if( Codes[j].ch == input[i] ) {
- flag = true ; Codes[j].times ++ ; break ;
- }
- }
- if( !flag ) {
- Codes[ammount].isLeaf = true ;
- Codes[ammount].l = NULL ;
- Codes[ammount].r = NULL ;
- Codes[ammount].ch = input[i] ;
- Codes[ammount++].times = 1 ;
-
- }
- i++ ;
- }
- Huffman *t = MergerCode( Codes , ammount) ; //合併codes
- SimpleSearch x(t) ;
- x.BFS() ; //走訪每個節點
- i = 0 ;
- //輸出coding的結果
- cout << "After encoding->" ;
- while ( input[i] != '\0' ) {
- //查表
- Huffman *t = x.first->next ;
- while (t != NULL ) {
- if ( t->ch == input[i] ) {
- cout << t->code << "|" ; break ;
- }
- t = t->next ;
- }
- i++ ;
- }
- cout << endl ;
- int s = 0 ;
- //統計總共要多少位元數
- while( x.first != NULL ) {
- if (x.first->ch != NULL )
- s += x.first->times * (int) strlen(x.first->code) ;
- x.first = x.first->next ;
- }
- cout << "Total bits->" << s << endl ;
- system("pause") ;
- return 0 ;
- }
複製代碼 裡面寫了linked list & tree結構,兩個寫在同一個struct裡面
Complier: vc++ 2008
剛剛試了一下輸入 / 輸出是OK的,給你參考看看!!... |
|