1. 程式人生 > >資料結構作業 哈夫曼樹

資料結構作業 哈夫曼樹

#include<bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;
set<int>st;
int Fre[10000];

typedef struct
{
		int weight;
		int parent, lchild, rchild;
}HTnode,*Huffmantree;

typedef char **Huffmancode;

void select(Huffmantree T, int p, int &s1, int &s2)
{
		int mini = inf;
		for (int i = 1; i <= p; i++)
		{
				if (st.count(i))continue;
				if (mini > T[i].weight)
				{
						mini = T[i].weight;
						s1 = i;
				}
		}
		st.insert(s1);
		mini = inf;
		for (int i = 1; i <= p; i++)
		{
				if (st.count(i)) continue;
				if (mini > T[i].weight)
				{
						mini = T[i].weight;
						s2 = i;
				}
		}
		st.insert(s2);
}

void CreatTree(Huffmantree &T, int n)
{
		if (n <= 1)
				return;
		int m = 2 * n - 1;
		T = new HTnode[m + 1];
		for (int i = 1; i <= m; i++)
		{
				T[i].parent = 0;
				T[i].lchild = T[i].rchild = 0;
		}
		for (int i = 1; i <= n; i++)
				T[i].weight = Fre[i];
		for (int i = n + 1; i <= m; i++)
		{
				int s1, s2;
				select(T, i - 1, s1, s2);
				T[s1].parent = i; T[s2].parent = i;
				T[i].lchild = T[s1].weight > T[s2].weight ? s2 : s1;
				T[i].rchild=T[s1].weight > T[s2].weight ? s1 : s2;
				T[i].weight = T[s1].weight + T[s2].weight;
		}
}

void CreatHuffmancode(Huffmantree T, Huffmancode &HC, int n)
{
		HC = new char *[n + 1];
		char *cd = new char[n];
		cd[n - 1] = '\0';
		for (int i = 1; i <= n; i++)
		{
				int start = n - 1;
				int c = i;
				int f = T[i].parent;
				while (f != 0)
				{
						--start;
						if (T[f].lchild == c)
								cd[start] = '0';
						else
								cd[start] = '1';
						c = f; f = T[f].parent;
				}
				HC[i] = new char[n - start];
				strcpy(HC[i], &cd[start]);
		}
		delete cd;
}

int  CreatFre(string s)
{
		set<int>fre;
		int cnt = 0;
		for (int i = 0; i < s.size(); i++)
		{
				if (isalpha(s[i]))
				{
						s[i] = tolower(s[i]);
						Fre[s[i] - 'a'+1]++;
						if (fre.count(s[i] - 'a')==0)
						{
								fre.insert(s[i] - 'a');
								cnt++;
						}
				}
		}
		return cnt;
}

void TravelTree(Huffmancode HC, int n)
{
		for (int i = 1; i <= n; i++)
		{
				printf("%c->", i + 96);
				for (int j = 0; HC[i][j] != '\0'; j++)
						printf("%c", HC[i][j]);
				puts("");
		}
		
}

/*void replace(string s,Huffmancode HC,ofstream outFile)
{
		
}*/
int main()
{
		ios::sync_with_stdio(false);
		ifstream inFile;
		ofstream outFile;
		outFile.open("outData.txt");
		inFile.open("SourceFile.txt");
		string s;
		printf("please input a string :");
		inFile>>s;
		int len=CreatFre(s);
		Huffmantree T;
	//	len++;
		CreatTree(T, len);
		Huffmancode HC;
		CreatHuffmancode(T, HC, len);
		TravelTree(HC, len);
		for (int i = 0; i < s.size(); i++)
		{
				if (isalpha(s[i]))
				{
						s[i] = tolower(s[i]);
						int t = s[i] - 'a' + 1;
						for (int j = 0; HC[t][j]; j++)
								outFile<<HC[t][j];
				}
		}
		inFile.close();
  		outFile.close();
		system("pause");
		return 0;
}