哈夫曼编码

转载请注明来源:http://blog.chinaunix.net/uid-26833883-id-3160434.html
前面一节我们知道了,怎样去创建一个哈夫曼树,这一节我们来看看哈夫曼编码。

思想:得到哈夫曼树后,自顶向下按路径编号,指向左节点的边编号0,指向右节点的边编号1,从根到叶节点的所有边上的0和1连接起来,就是叶子节点中字符的哈夫曼编码。

下图体现了哈夫曼编码的过程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//哈夫曼树结点
typedef struct HuffNode
{
    int weight;
    char ch;
    char code[20];
    struct HuffNode *rchild;
    struct HuffNode *lchild;
    
}HuffMan;

//队列设计
typedef struct _node_
{
    HuffMan *data;
    struct _node_ *next;
}ListNode;

typedef struct
{
    ListNode *front;
    ListNode *rear;
}Queue;

//create empty queue
Queue *create_empty_queue()
{
    ListNode *HList;
    Queue *Hqueue;

    HList = (ListNode *)malloc(sizeof(ListNode));
    HList->next = NULL;
    
    Hqueue = (Queue *)malloc(sizeof(Queue));
    Hqueue->front = Hqueue->rear = HList;

    return Hqueue;
}

//入队
int EnterQueue(Queue *head,HuffMan *data)
{
    ListNode *temp;

    temp = (ListNode *)malloc(sizeof(ListNode));
    temp->data = data;
    temp->next = NULL;

    head->rear->next = temp;
    head->rear = temp;

    return 0;
}

//有序插入结点
int OrderEnterQueue(Queue *head,HuffMan *p)
{
    ListNode *m = head->front->next;
    ListNode *n = head->front;
    ListNode *temp;

    while(m)
    {
        if(m->data->weight < p->weight)
        {
            m = m->next;
            n = n->next;
        }
        else{
            
            break;
        }
    }

    //插到最后一个结点
    if(m == NULL)
    {
        temp = (ListNode *)malloc(sizeof(ListNode));
        temp->data = p;
        temp->next = NULL;
        n->next = temp;
        head->rear = temp;

        return 0;
    }

    //插入中间结点
    temp = (ListNode *)malloc(sizeof(ListNode));
    temp->data = p;
    n->next = temp;
    temp->next = m;

    return 0;
}

//判断队列是否为空(注意,我们认为队列含有一个结点为空,想想为什么
//这样做?
int _is_empty_queue(Queue *head)
{
    if(head->front->next->next == NULL)
    {
        printf("is_empty_queue\n");
        return 1;
    }
    
    return 0;
}

//判断队列是否为空
int is_empty_queue(Queue *head)
{
    if(head->front == head->rear)
        return 1;
    else
        return 0;
}

//出队
HuffMan *DeleteQueue(Queue * head)
{
    ListNode *temp;

    temp = head->front;
    head->front = temp->next;
    free(temp);
    temp = NULL;

    return head->front->data;
}

//创建哈夫曼树
HuffMan *create_huffman_tree(Queue *head)
{
    HuffMan *right,*left,*current;

    //循环结束时,队列只含有一个结点
    while(!_is_empty_queue(head))
    {
        left = DeleteQueue(head);
        right = DeleteQueue(head);
        current = (HuffMan *)malloc(sizeof(HuffMan));
        current->weight = left->weight + right->weight;
        current->rchild = right;
        current->lchild = left;
        OrderEnterQueue(head,current);    
    }

    return head->front->next->data;
}

//哈夫曼编码
int HuffmanCode(HuffMan *root)
{
    HuffMan *current = NULL;
    Queue *queue = NULL;

    queue = create_empty_queue();

    EnterQueue(queue, root);

    while(!is_empty_queue(queue))
    {
        current = DeleteQueue(queue);

        if(current->rchild == NULL && current->lchild == NULL)
        {
            printf("%c:%d %s\n",current->ch,current->weight,current->code);
        }

        if(current->lchild)
        {
            strcpy(current->lchild->code,current->code);
            strcat(current->lchild->code,"0");
            EnterQueue(queue, current->lchild);
        }

        if(current->rchild)
        {
            strcpy(current->rchild->code,current->code);
            strcat(current->rchild->code,"1");
            EnterQueue(queue, current->rchild);
        }
    }

    return 0;
}

运行结果:
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值