哈夫曼树的实现

哈夫曼树的应用就不说了,主要是用于优化算法和文本压缩。

哈夫曼树的实现的原理还算比较简单的,至少我认为比红黑树简单,但是,哈夫曼树的实现的编码是个头疼的问题,它的实现有很多的细节,很难说哪一种实现是最好的,必须依据现实的具体情况进行设计,不过有几个细节还是可以说下的,比如找最小值可以使用小堆用于优化,至于编码是从根开始,还是从叶子开始,看具体情况吧!!!

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

using namespace std;

struct HufNode {
    int key;
    HufNode *lChild;
    HufNode *rChild;

    int nIndex;
    char code[BUFSIZ];
};

struct ListHufNode{
    HufNode *data;
    ListHufNode *next;
    ListHufNode *pre;
};

class List_Huf_Node {
public:
    List_Huf_Node() {
        head = new ListHufNode;
        memset(head, 0, sizeof(ListHufNode));
        tail = new ListHufNode;
        memset(tail , 0, sizeof(ListHufNode));
        head->next = tail;
        tail->pre = head;
    }
    ~List_Huf_Node() {
        delete head;
        delete tail;
    }

    void insert_huf_node(HufNode *huf_node) {
        ListHufNode *node = new ListHufNode;
        memset(node, 0, sizeof(ListHufNode));
        node->data = huf_node;
        node->pre = tail->pre;
        node->pre->next = node;
        node->next = tail;
        tail->pre = node;
    }

    void Get_Min_Min2_Huf_Node(HufNode **min_node, HufNode **min_node2) {
        ListHufNode *min, *min2;
        ListHufNode *p = head->next;
        min = min2 = NULL;
        while (p != tail) {
            if (min==NULL || p->data->key < min->data->key) {
                min2 = min;
                min = p;
            }
            else if (min2==NULL || p->data->key < min2->data->key) {
                min2 = p;
            }
            p = p->next;
        }

        *min_node = min->data;
        *min_node2 = min2->data;

        ListHufNode *pre = NULL;
        pre = min->pre;
        pre->next = min->next;
        pre->next->pre = pre;

        pre = min2->pre;
        pre->next = min2->next;
        pre->next->pre = pre;

        delete min;
        delete min2;
    }

    void GetFirstElement(HufNode **huf_node) {
        *huf_node = head->next->data;
        ListHufNode *cur = head->next;
        head->next = cur->next;
        head->next->pre = head;

        delete cur;
    }

    bool IsHaveMoreThanTwoElement() {
        return head->next!=tail && head->next->next!=tail;
    }

    bool IsEmpty() {
        return head->next==tail;
    }


private:
    ListHufNode *head;
    ListHufNode *tail;
};

void HuffmanCode(int a[], char codes[][BUFSIZ], int len) {
    assert(len>1);
    // 建立结点
    HufNode *node = NULL;
    HufNode *min_node = NULL;
    HufNode *min_node2 = NULL;
    List_Huf_Node list_huf_node;
    for (int i=0; i<len; ++i) {
        node = new HufNode;
        memset(node, 0, sizeof(HufNode));
        node->key = a[i];
        node->nIndex = i;
        list_huf_node.insert_huf_node(node);
    }

    while (list_huf_node.IsHaveMoreThanTwoElement()) {
        list_huf_node.Get_Min_Min2_Huf_Node(&min_node, &min_node2);
        node = new HufNode;
        memset(node, 0, sizeof(HufNode));
        node->key = min_node->key + min_node2->key;
        node->lChild = min_node;
        node->rChild = min_node2;
        list_huf_node.insert_huf_node(node);
    }

    while (list_huf_node.IsEmpty()==false) {
        list_huf_node.GetFirstElement(&node);
        if (node->lChild != NULL) {
            strcat(node->lChild->code, node->code);
            strcat(node->lChild->code, "0");
            list_huf_node.insert_huf_node(node->lChild);
        }
        if (node->rChild != NULL) {
            strcat(node->rChild->code, node->code);
            strcat(node->rChild->code, "1");
            list_huf_node.insert_huf_node(node->rChild);
        }

        if (node->lChild==NULL && node->rChild==NULL) {
            strcpy(codes[node->nIndex], node->code);
        }

        delete node;
    }
}

int main() {
    const int SIZE = 4;
    int a[SIZE] = {20, 40, 25, 15};
    char code[SIZE][BUFSIZ] = {0};

    HuffmanCode(a, code, SIZE);

    for (int i=0; i<SIZE; ++i) {
        printf("%d:%s\n", a[i], code[i]);
    }
    putchar('\n');

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值