資料結構_樹_赫夫曼樹及赫夫曼編碼_C++實現
阿新 • • 發佈:2018-12-22
#include<iostream> #include<stack> using namespace std; class NODE { public: NODE(); int weight,parent,lchild,rchild; }; NODE::NODE() { weight=parent=lchild=rchild=0; } class HUFFMAN { public: HUFFMAN(); void GetHuffmanCode();//獲得赫夫曼編碼主調函式 private: void GetHuffmanNode();//獲得節點 void HuffmanCoding();//編碼 void PrintHuffmanCode();//輸出編碼 void Select(int &,int &);//從森林中選擇兩顆權值較小的樹 int len,cur;//len表示表長度cur表示當前指示的節點 NODE * HT;//HT指向表頭結點 }; HUFFMAN::HUFFMAN() { len=cur=0; HT=NULL; } void HUFFMAN::GetHuffmanCode()//獲得赫夫曼編碼主調函式 { GetHuffmanNode(); HuffmanCoding(); PrintHuffmanCode(); } void HUFFMAN::GetHuffmanNode()//獲得節點 { cout<<"GetHuffmanNode Called !"<<endl<<endl; cout<<"Please Enter The Weight Of Each Node ."<<endl<<endl; NODE node[100]; int i=0,t; while(cin>>t) { node[i++].weight=t; } cin.clear(); len=i; HT=new NODE[2*i]; for(i=1;i<=len;i++) *(HT+i)=node[i-1]; cur=len+1; } void HUFFMAN::HuffmanCoding()//編碼 { cout<<"HuffmanCoding Called !"<<endl<<endl; while(cur<2*len)//建樹過程 { int a,b; Select(a,b);//選擇兩顆權值較小的子樹 (HT+cur)->weight=(HT+a)->weight+(HT+b)->weight;//連線成新樹並更該其權值 (HT+cur)->lchild=a; (HT+cur)->rchild=b; cur++; } } void HUFFMAN::PrintHuffmanCode()//輸出編碼 { cout<<"PrintHuffmanCode Called !"<<endl<<endl; cout<<"The Huffman Code Is :"<<endl<<endl; stack<int> s;//定義一個棧存放編碼 for(int i=1;i<=len;i++)//從葉子節點向上查詢到根節點 { cout<<(HT+i)->weight<<" : "; int j=i; do { if((HT+(HT+j)->parent)->lchild==j)//左子樹表示為0 s.push(0); else//右子樹表示為1 s.push(1); j=(HT+j)->parent;//j指向其父節點 }while((HT+j)->parent!=0);//未查詢到根節點時進行查詢 while(!s.empty())//輸出編碼 { cout<<s.top()<<" "; s.pop(); } cout<<endl; } } void HUFFMAN::Select(int &a,int &b)//從森林中選擇兩顆權值較小的樹 { int min; bool first=true; for(int i=1;i<cur;i++)//從表中獲得min的值並得到a其中有個小技巧不知道您看懂了木有? { if((HT+i)->parent==0&&(first==true||(HT+i)->weight<min)) { a=i; min=(HT+i)->weight; if(first==true) first=false; } } first=true; (HT+a)->parent=cur;//更改a的父節點 for(int i=1;i<cur;i++)//從表中獲得min的值並得到b { if((HT+i)->parent==0&&(first==true||(HT+i)->weight<min)) { b=i; min=(HT+i)->weight; if(first==true) first=false; } } (HT+b)->parent=cur;//更改b的父節點 if(a>b)//如有必要調整a、b次序 { int t=a; a=b; b=t; } }