Haffman编码/译码——数据结构作业(二)
来源:互联网 发布:苹果5没有移动3g网络吗 编辑:程序博客网 时间:2024/05/22 04:55
算法:Haffman,DFS
数据结构:queue,Haffman Tree
PS:使用链表建树,但用数组存树操作更方便
// Huffman.cpp : 定义控制台应用程序的入口点。////#include "stdafx.h"#include "iostream"#include "stdio.h"#include "stdlib.h" #include "string.h"#include "string"#include "queue"#include "fstream"const int max_nodenum=100; //最多字符数 using namespace std;struct Node{ char ch; double weight; Node* parent; Node* Lchild; Node* Rchild; Node() { ch = NULL; weight = 0; parent = NULL; Lchild = NULL; Rchild = NULL; } bool operator < (const Node &a)const { return a.weight < weight; }}Hf[max_nodenum]; //Hf[n]用来存储符号信息,和建树无关struct Info //打表保存字符编码信息{ char ch; string code;}info[max_nodenum];Node *root; //huffman树根void CreateTree(){ root = new Node; priority_queue <Node> Queue; ifstream fin("hfmTree.txt"); //在文件中读取已保存的数据 int n; fin >> n; for (int i = 0; i < n; i++) { fin >> Hf[i].ch >> Hf[i].weight; Queue.push(Hf[i]); } while (Queue.size() > 1) //建树 从下向上 { Node* a = new Node; //左子树 if (Queue.top().ch == NULL) { *a = Queue.top(); a->Lchild->parent = a; //***被坑了好久 a->Rchild->parent = a; //*** } a->ch = Queue.top().ch; a->weight = Queue.top().weight; Queue.pop(); Node *b = new Node; //右子树 if (Queue.top().ch == NULL) { *b = Queue.top(); b->Lchild->parent = b; //*** b->Rchild->parent = b; //*** } b->ch = Queue.top().ch; b->weight = Queue.top().weight; Queue.pop(); Node *ab = new Node; //父节点 ab->weight = a->weight + b->weight; ab->Lchild = a; ab->Rchild = b; a->parent = ab; b->parent = ab; Queue.push(*ab); if (Queue.size() == 1) root = ab; //树根 }}void Initial(){ int choose; cout << "建树:1.在控制台输入 2.在'hfmTree.txt'文件中读取" << endl; cin >> choose; if (choose == 1) { ofstream fclear("hfmTree.txt", std::ofstream::out | std::ofstream::trunc); //清空原有文件 cout << "控制台建树:输入字符集大小 n" << endl; ofstream fout("hfmTree.txt"); //在文件中输出 int n; cin >> n; fout << n << endl; cout << "输入:字符 权值" << endl; for (int i = 0; i < n; i++) //输入并输出到文件 { cin >> Hf[i].ch >> Hf[i].weight; fout << Hf[i].ch << " " << Hf[i].weight << endl; } CreateTree(); //文件中读取数据建树 cout << "建树成功,并保存到 'hfmTree.txt'中" << endl; } else if (choose == 2) { CreateTree(); //文件中读取数据建树 //cout << root->weight << " " << root->Lchild->parent->weight; cout << "文件中读取数据建树成功" << endl; } /* 4 a 5 s 10 d 15 f 10 */}/*void tv(Node* rot){ cout << rot->weight << " " << rot->ch << endl; if (rot->Lchild == NULL && rot->Rchild == NULL) return; //if(rot->ch!=NULL) if(rot->Lchild!=NULL) tv(rot->Lchild); if(rot->Rchild!=NULL) tv(rot->Rchild);}*/int info_num = 0; //字符编码信息数量 void Traverse(Node *rot){ if (rot->Lchild == NULL && rot->Rchild == NULL) { info[info_num].ch = rot->ch; Node* cur=rot; //cout << cur->weight << " " << cur->parent->parent->weight; while (cur->parent!=NULL) { //cout << cur->weight << " "<<cur->parent->weight; if (cur->parent->Lchild == cur) { info[info_num].code += '0'; } if (cur->parent->Rchild == cur) { info[info_num].code += '1'; } cur=cur->parent; } //cout << info[info_num].ch << " " << info[info_num].code << endl; int codelen = info[info_num].code.length(); for (int i = 0; i < codelen/2; i++) //逆置得正序编码 { int temp = info[info_num].code[i]; info[info_num].code[i] = info[info_num].code[codelen - i - 1]; info[info_num].code[codelen - i - 1] = temp; } info_num++; return; } if (rot->Lchild != NULL) Traverse(rot->Lchild); if(rot->Rchild!=NULL) Traverse(rot->Rchild);}void Encoding(){ info_num = 0; memset(info, 0, sizeof(info)); //初始化 Traverse(root); //遍历打表记录编码映射 cout << "编码映射如下:" << endl; for (int i = 0; i < info_num; i++) { cout << info[i].ch << " " << info[i].code << endl; } //tv(root); cout << "编码:1.控制台输入数据 2.从文件'ToBeTran.txt'中读取" << endl; int choose; cin >> choose; ofstream fout("CodeFile.txt"); //编码结果保存文件 if (choose == 1) { cout << "输入字符序列:" << endl; string str; cin >> str; //Traverse(root); //cout << 111000; /* for (int i = 0; i < info_num; i++) { cout << info[i].ch<<" "; cout << info[i].code<<endl; } */ for (int i = 0; i < str.length(); i++) { for (int j = 0; j < info_num; j++) { if (str[i] == info[j].ch) { cout << info[j].code; fout << info[j].code; } } } cout << endl; cout << "以上编码结果已保存到文件'CodeFile.txt'中" << endl; } else if (choose == 2) { ifstream fin("ToBeTran.txt"); string str; fin >> str; //Traverse(root); for (int i = 0; i < str.length(); i++) { for (int j = 0; j < info_num; j++) { if (str[i] == info[j].ch) { cout << info[j].code; fout << info[j].code; } } } cout << endl; cout << "以上编码结果已保存到文件'CodeFile.txt'中" << endl; }}void Decoding(){ string str; ifstream fin("CodeFile.txt"); fin >> str; ofstream fout("TextFile.txt"); Node* cur = root; int i=0; while (i <= str.length()) { if (cur->Lchild == NULL && cur->Rchild == NULL) { cout << cur->ch; fout << cur->ch; cur = root; } if (str[i] == '0') cur = cur->Lchild; if (str[i] == '1') cur = cur->Rchild; i++; } cout << endl; cout<< "以上译码结果已保存到文件'TextFile.txt'中" << endl;}int main(){ cout << "操作菜单:1.建Huffman树 2.编码 3.译码 0.结束"<<endl; int n; while (cin >> n && n) { switch (n) { case 1:Initial();break; case 2:Encoding(); break; case 3:Decoding();break; default:break; } cout << "操作菜单:1.建Huffman树 2.编码 3.译码 0.结束" << endl; } return 0;}
0 0
- Haffman编码/译码——数据结构作业(二)
- [数据结构]第五次作业:huffman编码及其译码(二)
- [数据结构]第五次作业:huffman编码及其译码(一)
- 数据结构课程设计——编码与译码
- 南邮数据结构实验二——哈夫曼编码/译码系统
- 哈夫曼编码译码(数据结构课程设计)
- 数据结构Huffman编码译码
- 数据结构笔记--haffman树与haffman编码分析
- 数据结构课程设计-哈夫曼编码译码
- 【数据结构】哈夫曼树实现编码译码
- Haffman编码
- Haffman编码
- Haffman 编码
- 哈夫曼树构建,编码,译码的实现------数据结构
- 数据结构实验,哈夫曼编码/译码系统
- 数据结构:哈夫曼树,哈夫曼编码与译码系统
- 【数据结构】哈夫曼树及哈夫曼编码译码
- 【数据结构基础】哈夫曼编码/译码课程设计
- 最近在 OS-10.9下配置opencv, cgal, latex, qt, pillow
- SQLite实时增删改查
- UIImage拉伸
- .properties文件的加载
- 使用Autolayout实现UITableView的Cell动态布局和高度的动态改变
- Haffman编码/译码——数据结构作业(二)
- iOS 编程小技巧
- 欢迎使用CSDN-markdown编辑器
- 乐观锁与悲观锁
- 物体表面滚动纹理
- iOS导入字体
- Apache Tomcat安装、配置、启动与后续操作步骤
- jsp 400 The request sent by the client was syntactically incorrect. springMVC
- char *p = "abcdefg"; p[0] = p[1]出错