/****************************************************************************************
--程序描述: 上机实验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应用
最新推荐文章于 2022-11-02 10:32:35 发布
2366

被折叠的 条评论
为什么被折叠?



