Haffman应用

/****************************************************************************************
--程序描述:	上机实验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);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值