數據結構實驗5-哈夫曼編碼

實驗內容

某報文中共出現abdeoy 等6個字符,各字符出現頻度依次爲12 6 4 1 2 8。要求:

  1. 實現哈弗曼編碼算法,對這6個字符求出各自的編碼;
  2. 實現哈弗曼譯碼算法,對給定的一組編碼(110011111101110110),譯出其對應的報文部分 。

程序代碼

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
typedef int ElemType;
typedef int Status;
typedef int Boolean;
typedef struct {
    int weight,id;
    unsigned int parent, lchild,rchild;
}HTNode, *HuffmanTree;
typedef char * * HuffmanCode;
typedef struct{
    int w;
    char c;
}temp;
void Select(HuffmanTree & HT, int tag, int & s1, int &s2)
{
    int minnum = 1e9, pos = -1;
    for(int i = 1; i<=tag;++i){
        if(HT[i].weight<minnum && HT[i].parent == 0){
            minnum = HT[i].weight;
            pos  = i;
        }
    }
    s2 = pos;
    HT[pos].parent = tag+1;
    minnum = 1e9, pos  = -1;
    for(int i = 1;i<=tag;++i){
        if(HT[i].weight<minnum && HT[i].parent == 0){
            minnum = HT[i].weight;
            pos  = i;
        }
    }
    s1 = pos;
    HT[pos].parent = tag+1;
}
void output(HuffmanTree & HT, int m)
{
    printf("    i     w     lc    rc    pa\n");
    for(int i = 1 ;i<=m;++i){
        printf("%5d %5d %5d %5d %5d\n",i,HT[i].weight,HT[i].lchild,HT[i].rchild,HT[i].parent);
    }
}
bool cmp(HTNode h1, HTNode h2)
{
    if(h1.weight<h2.weight) return true;
    else return false;
}
bool cmpt(temp a, temp b)
{
    if(a.w > b.w) return false;
    else return true;
}
void HuffmanCoding(HuffmanTree & HT, HuffmanCode &HC, int *w , int n)
{
    if(n<=1) return;
    int m = 2 * n -1 ;
    HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));
    int i = 1;
    HuffmanTree p = HT;
    for(;i<=n; ++i,++p,++w){
        HT[i] = {*w,i,0,0,0};
    }
    for(i = n+1 ;i<=m;++i,++p)
        HT[i]= {0,i,0,0,0};
    for(int i = n+1;i<=m;++i){
        int s1, s2;
        Select(HT,i-1,s1,s2);
        if(s2<=n) swap(s1,s2);
        //HT[s1].parent = i; HT[s2].parent = i;
        HT[i].lchild = s1; HT[i].rchild = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;
    }
    HC = (HuffmanCode)malloc((n+1) * sizeof(char *));
    char * cd = (char *)malloc( n * sizeof(char));
    cd[n-1] = '\0';
    for(int i = 1; i<=n;++i){
        int start = n-1;
        unsigned int f = HT[i].parent;
        for( int c = i,f = HT[i].parent; f!=0 ;c = f,f = HT[f].parent)
            if(HT[f].lchild == c) cd[--start] = '0';
            else cd[--start] = '1';
        HC[i] = (char*)malloc((n-start) * sizeof(char));
        strcpy(HC[i],&cd[start]);
    }
    free(cd);
}
void uncoding(HuffmanTree & HT, int n,char * s)
{
    char str[1000] = "110011111101110110";
    printf("|"); printf("       請輸入想要解碼的01串        ") ;printf("|\n");
    scanf("%s",str);
    printf("|"); printf("          譯碼的結果爲             ") ;printf("|\n");
    int len = strlen(str);
    HuffmanTree t = &HT[2*n-1];
    for(int i = 0; i<len;++i){
        if(str[i] == '0'){
            t = &HT[t->lchild];
        }else{
            t = &HT[t->rchild];
        }
        if(t->id<=n){
            printf("%c",s[t->id-1]);
            t = &HT[2*n-1];
            continue;
        }
    }
    printf("\n");
}
void Paint()
{
    printf("|"); printf("       The Experiment Of Tree        ") ;printf("|\n");
    printf("|"); printf("              Huffman                ") ;printf("|\n");
    printf("|"); printf("        Author: Luo Peng Fei         ") ;printf("|\n");
    printf("|"); printf("          Date:2017/5/3              ") ;printf("|\n");
}
int main()
{
    Paint();
    HuffmanTree HT ;
    HuffmanCode HC;
    printf("|"); printf("       請輸入想要編碼的字符          ") ;printf("|\n");
    char str[30] = {'a','b','d','e','o','y'};
    scanf("%s",str);
    printf("|"); printf("       請依次輸入字符的頻率          ") ;printf("|\n");
    int fre[30] = {12, 6, 4, 1, 2, 8};
    for(int i = 0; i<strlen(str);++i) scanf("%d",&fre[i]);
    temp t[30];
    for(int i = 0; i<strlen(str);++i){
        t[i].w = fre[i];
        t[i].c = str[i];
    }
    HuffmanCoding(HT,HC,fre,strlen(str));
    printf("|"); printf("          編碼的結果爲               ") ;printf("|\n");
    for(int i = 1; i<=strlen(str) ;++i){
        printf("%c : ",t[i-1].c);
        printf("%s\n",HC[i]);
    }
    printf("\n");
    uncoding(HT,strlen(str),str);
    return 0;
}

運行結果

這裏寫圖片描述

哈夫曼樹的結構
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章