双向树的建立实现哈夫曼的编码:
#include <bits/stdc++.h>
using namespace std;
struct betalist {
int quan;
char tu;
};
struct haffman {
int quan;
struct betalist* ncp = NULL;
struct haffman* left = NULL;
struct haffman* right = NULL;
struct haffman* father = NULL;
};
//struct betalist* head = NULL;
struct haffman* head = NULL;
struct betalist* P;
int cmp(struct betalist A,struct betalist B) {
return A.quan < B.quan;
}
struct haffman* add(struct betalist* A) {
if (head == NULL) {
head = new struct haffman;
head->ncp = A;
head->quan = 1; //
return head;
}
else {
struct haffman* tmp1 = new struct haffman;
struct haffman* tmp2 = new struct haffman;
tmp1->ncp = A;
tmp1->quan = 0; //
tmp2->left = tmp1;
tmp2->right = head;
tmp2->quan = 1; //
head->father = tmp2;
tmp1->father = tmp2;
return head = tmp2;
}
}
void newhuffman() { //
int zf;
char stmp[100];
if (head != NULL) {
printf("哈夫曼树已经建立\n");
return;
}
printf("需要建立的字符个数:");
scanf("%d", &zf);
getchar();
P = new struct betalist[zf];
printf("请以字符串的方式输入字符:");
for (char s, *q = stmp; s = getchar(), s != '\n'; q++) {
*q = s;
*(q + 1) = 0;
}
for (int i = 0; i < zf; i++)
P[i].tu = stmp[i];
printf("请输入%d个字符的权值(空格间隔):",zf);
for (int i = 0; i < zf; i++) {
scanf("%d", &P[i].quan);
}
sort(P, P + zf, cmp); // 排序 将权值小的排在前面 -> 权值大的排在后面
for (int i = 0; i < zf; i++) // 建树开始
add(&P[i]); // 加边
}
void deletehuffman(struct haffman *S) {
if (P != NULL)
free(P);
if (S == NULL)
return;
deletehuffman(S->left);
deletehuffman(S->right);
free(S);
}
struct haffman* Ktmp;
void finds(char T,struct haffman* h = head) {
if (h == NULL)
return;
if ((h->ncp) != NULL && h->ncp->tu == T) {
Ktmp = h;
return;
}
finds(T, h->left);
finds(T,h->right);
}
void HuffmanNO_(char st) { // 编码可能要 01 背包求解
finds(st);
if (!Ktmp) {
printf("字符%c不存在无法进行编码", st);
}
stack<int>STE;
for (struct haffman* i = Ktmp; i != head; i = i->father) {
STE.push(i->quan);
}
for (; STE.size(); STE.pop())
printf("%d",STE.top());
}
void Huffmansolve(char ns[]) {
int* zh = new int[strlen(ns)];
for (int i = 0, j = strlen(ns); i < j; i++)
zh[i] = ns[i] - '0';
int tn = 0;
int pd = 0;
struct haffman* i;
if (head == NULL) {
printf("哈夫曼编码还未建立 无法解密\n");
return;
}
for (i = head;i!=NULL&&tn<strlen(ns);) { // 没有遍历完树
if (zh[tn] == 0) {
if (i->left) {
i = i->left;
tn++;
pd = 1;
}
else {
if(i->ncp)
printf("%c", i->ncp->tu);
i = head;
pd = 0;
}
}
else if (zh[tn] == 1) {
if (i->right) {
i = i->right;
tn++;
pd = 1;
}
else {
if (i->ncp)
printf("%c", i->ncp->tu);
i = head;
pd = 0;
}
}
}
if (tn >= strlen(ns) && pd && i->ncp) {
printf("%c", i->ncp->tu);
}
else {
printf("哈夫曼编码有问题");
}
}
void solve() {
int x;
char st[900];
printf("哈夫曼树编码程序\n");
printf("作者:吴祖颂\n");
while (1) {
printf("1->构造哈夫曼编码 2->加密 3->解密哈夫曼编码 4->结束:");
scanf("%d", &x);
if (x == 1) {
newhuffman();
}
else if (x == 2) {
if (head == NULL) {
printf("Huffman树没有建立,无法编码");
}
else {
printf("输入待加密的单词或字母:");
cin >> st;
for (int i = 0, j = strlen(st); i < j; i++)
HuffmanNO_(st[i]);
}
printf("\n");
}
else if (x == 3) {
printf("请输入待解密的哈夫曼编码:");
cin >> st;
Huffmansolve(st);
printf("\n");
}
else if (x == 4)
break;
}
}
int main() {
solve();
system("pause");
return 0;
}