• 不定长哈夫曼树


    原理参考《算法导论》,我借用了stl中的deque类,这样方便构造书中说的有序队列Q。其次,本博客的所有代码都采用C和C++混编形式,所以建议使用VS2015及其以上版本编译代码。

    代码如下

    声明一个Huffman类以及对应的节点数据

    typedef struct _Huffnode {
        _Huffnode(int _key, int _freq)
            :p(NULL), l(NULL), r(NULL), key(_key), freq(_freq) {}
        ~_Huffnode() {
            //printf("%c delete
    ", key);
        }
        int freq, key;
        _Huffnode *l, *r, *p;
    }Huffnode, *pHuffnode;
    
    struct Compare {
        bool operator()(const  _Huffnode *lhs, const _Huffnode *rhs) {
            return lhs->freq < rhs->freq;
        }
    };
    
    class Huffman {
    public:
        Huffman(int *keys, int *freqs, int n) :huffman_root(NULL) {
            Huffman_init(keys, freqs, n);
        }
        ~Huffman(){
            Huffman_empty(huffman_root);
        }
        Huffnode *Huffman_root();
        Huffnode *Huffman_init(int *keys, int *freqs, int n);
        void Huffman_print(Huffnode *x, std::string str);
        void Huffman_empty(std::deque<Huffnode *> x);
    private:
        std::deque<Huffnode *> Q, huffman_root;//优先队列
    };

    对应的成员函数实现

     Huffman_init成员函数,构建Huffman树

    Huffnode *Huffman::Huffman_init(int *keys, int *freqs, int n) {
        Huffnode *q, *left, *right;
        for (int i = 0; i < n; i++) {
            q = new Huffnode(keys[i], freqs[i]);
            Q.insert(std::upper_bound(Q.begin(), Q.end(), q, Compare()), q);//从小到大的排序
        }
        for (std::deque<Huffnode *>::iterator itr = Q.begin(); itr != Q.end(); itr++)
            printf("%c:%d ", (*itr)->key, (*itr)->freq);
        printf("
    ");
        while (Q.size() != 1) {//至少保证有两个节点
            left = Q[0];
            Q.pop_front();
            right = Q.front();
            Q.pop_front();//两个次小节点
            q = new Huffnode('.', left->freq + right->freq);
            q->l = left;
            q->r = right;
            Q.insert(std::upper_bound(Q.begin(), Q.end(), q, Compare()), q);//加入到队列
            huffman_root.push_front(q->r);
            huffman_root.push_front(q->l);
        }
        q = Q.front();
        Q.pop_front();
        huffman_root.push_front(q);
        return huffman_root[0];
    }

    Huffman_print成员函数,输出对应的关键字key的变长字码

    void Huffman::Huffman_print(Huffnode *x, std::string str) {
        if (x == NULL) return;
        if (x->key != '.')//跳过节点'.'
            printf("%c:%s
    ", x->key, str.c_str());
        Huffman_print(x->l, str + "0");
        Huffman_print(x->r, str + "1");
    }

    Huffman_empty成员函数

    void Huffman::Huffman_empty(std::deque<Huffnode *> x) {
        while (!x.empty()) {
            delete x.back();
            x.pop_back();
        }
    }

    数据录入

    int key[] = { 'f','e','c','b','a','d' }, freq[] = { 5,9,12,13,45,16 };

    Main函数

    int main()
    {
        int key[] = { 'f','e','c','b','a','d' }, freq[] = { 5,9,12,13,45,16 };
        Huffman *huff=new Huffman(key, freq, sizeof(key) / sizeof(key[0]));
        huff->Huffman_print(huff->Huffman_root()," ");
        printf("对象释放....
    ");
        delete huff;
        if (_CrtDumpMemoryLeaks())
            printf("内存泄漏,请使用F5 debug模式查看!
    ");//内存泄漏检测
        else
            printf("无内存泄漏!
    ");
        return 0;
    }

    结果图

    对应树上的结果

    代码均经过测试,结果正确!

  • 相关阅读:
    oracle 视图views
    5分钟把任意网站变成桌面软件
    Angular http跨域
    jQuery版本升级踩坑大全
    redis 模糊删除key
    jedisCluster 报错: redis.clients.jedis.exceptions.JedisClusterException: No way to dispatch this command to Redis Cluster because keys have different slots.
    mac电脑复制键失灵
    java8 for ,forEach ,lambda forEach , strean forEach , parller stream forEach, Iterator性能对比
    linux光标操作
    redis hashmap数据结构分析
  • 原文地址:https://www.cnblogs.com/dalgleish/p/9186926.html
Copyright © 2020-2023  润新知