/**************************************************************************************** --程序描述: 上机实验4_树的应用.doc(有描述) --修改记录: 从前写的代码不够规范——2009.6.18 --修改人: 吴强 --输入要求: 输入1,建立成Haffman树 —输入字符个数 —(输入字符类型,字符出现频度)*字符个数 输入2,用Haffman树形成编码 输入3,根据编码还原成数据保存在ToBeTran文件中 ****************************************************************************************/ #include #include #include #include #include const int N=27; //26个字母和空格的个数 const int M=2*N-1; const int Max=10000; //设一较大值,便于比较 typedef struct { char c; int Weight; int lint; int rint; }Tnode; struct Node { char key; char coding[30]; }node[N]; //保存各字符的编码 std::fstream HfmFile; class myStack { private: int stack[N]; int top; public: myStack(); void Push(int); void Pop(); void PutStack(); }; myStack::myStack() { for (int i = 0; i < N; i++) { stack[i] = Max; } top = -1; } void myStack::Push(int x) { stack[++top] = x; } void myStack::Pop() { stack[top] = Max; top--; } void myStack::PutStack() { for (int i = 0; i <= top; i++) { HfmFile << stack[i]; } HfmFile << '/n'; } class huffman { public: huffman(); void Create_ht(); void TraverseTree(int); void Sort(); public: myStack code; Tnode hTree[M]; }; huffman::huffman() { hTree[0].c = ' '; hTree[0].Weight = 0; hTree[0].lint = -1; hTree[0].rint = -1; for (int i = 1; i < N; i++) { hTree[i].c = 'A'+i-1; hTree[i].Weight = 0; hTree[i].lint = -1; hTree[i].rint = -1; } for (i = N; i < M; i++) { hTree[i].c = '#'; hTree[i].Weight = Max; hTree[i].lint = -1; hTree[i].rint = -1; } } void huffman::Create_ht() { int i=0; int j = N; int k = N; int min_1; int min_2; while(j < M) { if (i < N && hTree[i].Weight <= hTree[j].Weight) { min_1 = i++; if (i < N && hTree[i].Weight <= hTree[j].Weight) { min_2=i++; } else { min_2=j++; } } else { min_1 = j++; if (i < N && hTree[i].Weight <= hTree[j].Weight) { min_2 = i++; } else { min_2 = j++; } } hTree[k].Weight = hTree[min_1].Weight + hTree[min_2].Weight; hTree[k].lint = min_1; hTree[k].rint = min_2; k++; } } void huffman::TraverseTree(int root) { if (hTree[root].rint != -1) { code.Push(0); TraverseTree(hTree[root].rint); code.Pop(); code.Push(1); TraverseTree(hTree[root].lint); code.Pop(); } else { HfmFile << hTree[root].c << '-'; code.PutStack(); } } //冒泡法按权值小到大排序 void huffman::Sort() { Tnode jh; for (int i = 0; i < N; i++) { int k = 0; for (int j = 0; j < N-i+1; j++) { if (hTree[j].Weight > hTree[j+1].Weight) { jh = hTree[j]; hTree[j] = hTree[j+1]; hTree[j+1] = jh; k = 1; } } if (!k) { break; } } } void inHfmData() { char ch; int i=0; int j=0; int k; HfmFile.open("hfmTree.txt",std::ios::in); while (!HfmFile.eof()) { HfmFile.get(ch); if (HfmFile.eof()) { break; } if (ch >= 'A' && ch <= 'Z') { node[i].key = ch; } else if (ch >= '0' && ch <= '1') { node[i].coding[j++] = ch; } else if(ch == '/n') { node[i].coding[j] = '/0'; i++; j = 0; } } HfmFile.close(); //对数据按字母大小排序 for (i = 0; i < N; i++) { struct Node t; k=0; for (j = 0; j < N-1; j++) { if(node[i].key < node[j].key) { t = node[i]; node[i] = node[j]; node[j] = t; k = 1; } } if(!k) { break; } } } void Initialization() { char ch; char c; int nSize; int w; huffman ht; HfmFile.open("hfmTree.txt",std::ios::out); cout << "input Character size: "; cin >> nSize; cout << "<字符>,<权值>" << endl; for (int i = 0; i < nSize; i++) { cin >> ch >> c >> w; ht.hTree[ch-'A'+1].Weight = w; } for (i = 0; i < N; i++) { cout << ht.hTree[i].c << ' ' << ht.hTree[i].Weight << endl; } ht.Sort(); ht.Create_ht(); ht.TraverseTree(M-1); HfmFile.close(); } //编码操作 void Encodeing() { char ch; inHfmData(); std::ifstream ToBFile("ToBeTran.txt"); std::ofstream CodeFile("CodeFile.txt"); while (!ToBFile.eof()) { ToBFile.get(ch); if (ToBFile.eof()) { break; } if (ch >= 'A' && ch <= 'Z') { CodeFile.write(node[ch-'A'+1].coding,strlen(node[ch-'A'+1].coding)); } else if (' ' == ch) { CodeFile.write(node[0].coding,strlen(node[0].coding)); } } CodeFile.close(); ToBFile.close(); cout << "OK.." << endl; } void Decoding() { char ch; char str[30]; int i = 0; int j = 0; inHfmData(); std::ifstream CodeFile("CodeFile.txt"); std::ofstream TextFile("TextFile.txt"); strcpy(str,""); while (!CodeFile.eof()) { CodeFile.get(ch); if (CodeFile.eof()) { break; } str[i++] = ch; str[i] = '/0'; for (int j = 0; j < N; j++) { if (!strcmp(node[j].coding,str)) { i = 0; TextFile.put(node[j].key); break; } } } TextFile.close(); CodeFile.close(); cout << "Is OK.." << endl; } void PrintFile() { char ch; std::ifstream CodeFile("CodeFile.txt"); std::ifstream TextFile("TextFile.txt"); cout << "CodeFile Content: " << endl; for (int i = 1; !CodeFile.eof(); i++) { CodeFile.get(ch); cout<> oper; switch (oper) { case 1: { Initialization(); break; } case 2: { Encodeing(); break; } case 3: { Decoding(); break; } case 4: { PrintFile(); break; } case 0: { break; } default: { cout<<"No operator.."<< endl; break; } } }while (oper != 0); }
Haffman应用
最新推荐文章于 2024-07-25 17:04:43 发布