经典贪心,哈夫曼编码。

#include <queue>
#include <string>
#include <vector>
#include <iostream>
using namespace std;

vector<int> V;

struct Node {
    int len;
    Node* right;
    Node* left;
    Node(int x = 0) :
        len(x), right(NULL), left(NULL) {}
};

class Op {
public:
    bool operator()(Node* const lhs, Node* const rhs) {
        return lhs->len > rhs->len;
    }
};

priority_queue<Node*, vector<Node*>, Op> Q;

int dfs(Node* p, int level) {
    if(!p) return 0;
    if(p -> left || p -> right)
        return dfs(p->left, level + 1) +
            dfs(p->right, level + 1);
    else return p->len * level;
}

void destroy(Node* p) {
    if(!p) return;
    destroy(p->left);
    destroy(p->right);
    delete p;
}

int main() {
    // 字符频数
    int C[128] = {};
    // 字符集
    string st = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    // 频度
    int f[] = {186, 64, 13, 22, 32, 103, 21, 15, 47, 57, 1, 5, 32, 20,
    57, 63, 15, 1, 48, 51, 80, 23, 8, 18, 1, 16, 1};
   
    // 总频数
    int all = 0;
   
    for(int i = 0; i < st.size(); ++i) {
        C[st[i]] = f[i];
        all += f[i];
    }

    // 生成基础节点
    for(int i = 1; i < 128; ++i)
        if(C[i]) Q.push(new Node(C[i]));
    // 替换指针,截取节点
    Node *x, *y, *z;
    // 优先队列合并
    while(!Q.empty()) {
        x = Q.top();
        Q.pop();
        if(Q.empty()) break;
        y = Q.top();
        Q.pop();
        z = new Node(x->len+y->len);
        z -> left = x;
        z -> right = y;
        Q.push(z);
    }
    int p = dfs(x, 0), q = 8 * all;
    if(x->left == NULL && x->right == NULL) p = x -> len;
    destroy(x);
    printf("%d %d %.1lf\n", q, p, double(q)/p);
    system("pause");
}

posted @ 2012-06-29 17:27  byfei  阅读(172)  评论(0编辑  收藏  举报