1. 程式人生 > >哈夫曼樹的編碼與解碼

哈夫曼樹的編碼與解碼

#include<stdio.h> #include<stdlib.h> #include<iostream> #include<string> using namespace std; #define MAXSIZE 30

typedef struct node {     int data;     char value;     struct node *lchild, *rchild;     struct node *next; }*TreeLink,Link;

TreeLink CreateTree(int n) {     TreeLink link = NULL, p = NULL, q = NULL, s = NULL;     int i;     link = (TreeLink)malloc(sizeof(Link));     link->lchild = link->lchild = link->next = NULL;     s= (TreeLink)malloc(sizeof(Link));     cout << "請輸入葉子的權值" << endl;     cin >> s->data;     cout << "請輸入葉子的值" << endl;     cin >> s->value;     s->lchild = s->rchild = s->next = NULL;     link->next = s;     for (i = 2; i <= n; i++)     {         s= (TreeLink)malloc(sizeof(Link));         cout << "請輸入葉子的權值" << endl;         cin >> s->data;         cout << "請輸入葉子的值" << endl;         cin >> s->value;         s->lchild = s->rchild = s->next = NULL;         q = link;         p = q->next;         while (p != NULL)         {             if (s->data < p->data)             {                 s->next = p;                 q->next = s;                 break;             }             else             {                 q = p;                 p = p->next;             }         }         if (p == NULL)         {             q->next = s;

        }     }     return link; }

void Print(TreeLink h) {     TreeLink p = h->next;     while (p != NULL)     {         cout << "權值為:" <<p->data<<endl;         p = p->next;     }     printf("\n"); }

TreeLink HuffTree(TreeLink link) {     TreeLink p = NULL, q = NULL, s = NULL;     while (link->next != NULL)     {         p = link->next;         q = p->next;         if (q->next != NULL)             link->next = q->next;         else         {             link->next = NULL;         }         s= (TreeLink)malloc(sizeof(Link));         s->data = p->data + q->data;         cout << "s->data" << s->data << endl;         s->next = NULL;         s->lchild = p;         s->rchild = q;         q = link;         p = q->next;         while (p != NULL)         {             //順序插入,不要破壞連結串列的從小到大的順序             if (s->data <= p->data)             {                 q->next = s;                 s->next = p;                 break;             }             else             {                 q = p;                 p = p->next;

            }             if (q != NULL && s->data > q->data)             {                 q->next = s;                 s->next = p;             }         }              }     return s; } void HuffCode(TreeLink p) {     TreeLink stack[MAXSIZE], q = NULL;     int b, i = -1, j = 0, k, code[MAXSIZE];     do     {         while (p != NULL)         {             if (p->lchild == NULL && p->rchild == NULL)             {                 cout << "p->data:" << p->data << endl;//輸出葉子結點的權值                 for (k = 0; k < j; k++)//輸出編碼                     cout << code[k];                 cout << endl;                 cout << "該葉子的值為:" << p->value << endl;//輸出值                 j--;             }             stack[++i] = p;//指向當前結點的指標p入棧             p = p->lchild;//p指向p的左孩子             code[j++] = 0;//對應的左分支上編碼0         }         //棧頂結點已經沒有左孩子或是其左子樹上的結點都已被訪問         q = NULL;         b = 1;//置已訪問過的標記         while (i >= 0 && b)//棧不空且棧頂結點的左子樹已經遍歷過         {             p = stack[i];//取出當前棧頂儲存的結點指標             if (p->rchild ==q)//當前棧頂結點p無右孩子或右孩子已經訪問             {                 i--;                 j--;                 q = p;//q指向剛訪問過的結點p             }             else//當前棧頂p有右子樹             {                 p = p->rchild;//p指向當前棧頂結點的右孩子結點                 code[j++] = 1;//對應的右分支編碼置1                 b = 0;//置右孩子結點未遍歷過其右子樹標記             }         }     } while (i >= 0);//當棧非空時繼續遍歷 } void PreOrder(TreeLink head) {     if (head)     {         cout << head->data << endl;         PreOrder(head->lchild);         PreOrder(head->rchild);     } }

void decodeing(string str, TreeLink head) {     TreeLink temp = head;     int i = 0;     while (str[i] != '\n' && temp->lchild && temp->rchild)     {         if (str[i] - 48 == 0 )         {             temp = temp->lchild;         }         else         {             if (str[i] - 48 == 1 )                 temp = temp->rchild;         }         i++;     }     cout << "解碼的值為:" << temp->value; }

int main() {     int n;     cout << "請輸入結點的個數" << endl;     cin >> n;     TreeLink head = CreateTree(n),s=NULL;     Print(head);     cout << "HuffmanTree" << endl;     s = HuffTree(head);     PreOrder(s);     cout << "編碼" << endl;     HuffCode(s);     string str;     for (int i = 0; i < 3; i++)     {         cout << "請輸入你想要解的碼" << endl;         cin >> str;         decodeing(str, s);     }     return 0; }