哈夫曼编码的贪心算法 二叉树结构表示

哈夫曼编码的贪心算法 二叉树结构表示

实验内容:

[参考数据类型或变量]

typedef ElemType chartypedef struct node{
     int w;
    int flag;
    ElemType c;
    struct node *plink,*llink,*rlink;
    char code[m];

}Node;

Node *num[n], *root;

[参考子程序接口与功能描述]
void SetTree( NODE *root )
功能: 从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树
void EnCode( Node *p )
功能: 利用已建好的哈夫曼树,对输入的正文进行编码
void DeCode( void )
功能: 利用已建好的哈夫曼树,将输入的代码进行译码

程序源代码

#include<bits/stdc++.h> 
#define maxn 20   //最大结点数目 
#define inf 0xfffffff //无穷大  

typedef struct node { 
    double w;     //权值
    int flag;     
    int c;       
    struct node *plink,*llink,*rlink;     
    char code[maxn];     
    int codelen; 
    node(){  //初始化节点     
        flag=0; 
        llink=NULL;         
        plink=NULL;         
        rlink=NULL;         
        codelen=0;     
    } 
}node;  
node *num[2*maxn-1];//指针数组 
int n;  

void SetTree(node *&root){//从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树 
    scanf("%d",&n);
    for(int i = 0; i < n;i++){
        num[i] = new node();
        num[i]->c = i;
        scanf("%lf",&num[i]->w);  //输入权重
    }
    int m = n;

    double min1 , min2;
    int pos1 = 0, pos2 = 0;
    for(int i = 0; i < m-1;i++){
        //找到最小两个节点
        min1 = inf; min2 = inf;
        for(int j = 0; j < n; j++){
            if(num[j]->flag == 0 ){
                if(num[j]->w < min1){
                    min2 = min1;
                    min1 = num[j]->w;
                    pos2 = pos1;
                    pos1 = j;
                }
                else if(num[j]->w < min2){
                    min2 = num[j]->w;
                    pos2 = j;
                }
            }
        }  
        //结点合并
        num[pos1]->flag = 1;
        num[pos2]->flag = 1;
        num[n] = new node();
        num[n]->c = -1;
        num[n]->w  = num[pos1]->w + num[pos2]->w;
        num[n]->llink = num[pos1]      ;
        num[n]->rlink = num[pos2];
        num[pos1]->plink = num[n];
        num[pos2]->plink = num[n];
        n++;
    }
    root = num[n-1];
    n = m;
}

void Encode(node *&root,int deep, char code[]){//利用已建好的哈夫曼树,对输入的正文进行编码 
    if(root->c != -1){
        for(int i = 0; i < deep;i++){
            root->code[i] = code[i];
        }
        root->codelen = deep;
        return;
    }
    code[deep] = '0'; //左节点编码0
    Encode(root->llink,deep+1,code);
    code[deep] = '1';//右节点编码 1
    Encode(root->rlink,deep+1,code);
}

void DeCode(node *&root, char code[] ){ //利用已建好的哈夫曼树,将输入的代码进行译码
    node *p = root;
    int len = strlen(code);
    int ans[maxn],anslen = 0;
    for(int i = 0; i < len ; i++){
        if(code[i] == '0'){
            p = p->llink;
        }
        else p = p->rlink;
        if(p->c != -1){
            ans[anslen++] = p->c;
            p = root;
        }
        if(p->llink == NULL || p->rlink == NULL){
            printf("输入的数据不在哈夫曼树中\n");
            return;
        }
    }
    printf("输入的译码为:");
    for(int i = 0; i < anslen; i++){
        printf("%d",ans[i]);
    }
    printf("\n");
}

void print(){
    for(int i= 0; i < n; i++){
        printf("%.2f: ",num[i]->w);
        for(int j = 0; j < num[i]->codelen;j++){
            printf("%c",num[i]->code[j]);
        }
        printf("\n");
    }
}

int main(){
    node *root = NULL;
    root = new node();

    SetTree(root);
    char code[maxn*maxn];
    Encode(root,0,code);
    print();
    printf("按上述规则输入代码:\n");
    scanf("%s",code);
    DeCode(root,code);
    return 0;
}

程序结果

在这里插入图片描述

分析讨论

哈夫曼问题的贪心选择性质和最优子结构性质证明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值