哈夫曼树(数组实现)

哈夫曼树的定义

带权路径长度 设二叉树有n个叶子节点,每个叶子节点带有权值Wk,从根节点到每个叶子节点的长度为Lk,则每个叶子结点的带权路径之和就是WPL= i = 1 n \sum_{i=1}^n Wi*Li
最优二叉树或哈夫曼树:就是WPL最小的二叉树

哈夫曼树的性质
  • 没有度为1的节点
  • 对于同一组权值,存在不同构的哈夫曼树
  • n个叶子节点的哈夫曼树共有2*n-1个结点
#include<iostream>
#include<stdlib.h>
#include<limits.h>
#include<string.h>
using namespace std;
struct Node{// 定义哈夫曼树的节点 左孩子右孩子父亲节点都是-1
    char data;
    int weight;
    int parent = -1;
    int left = -1;
    int right = -1;
};
int realSize;
Node HuffmanTree[200];
struct TwoMin{
    int one;
    int two;
};
TwoMin findTwoMin(){
    int minFirst = INT_MAX;
    int one,two;
    for(int i = 1;i<=realSize;i++){
        if(HuffmanTree[i].parent==-1&&HuffmanTree[i].weight<minFirst){
                minFirst = HuffmanTree[i].weight;
                one = i;
        }
    }
    minFirst = INT_MAX;
    for(int i = 1;i<=realSize;i++){
        if(HuffmanTree[i].parent==-1&&HuffmanTree[i].weight<minFirst&&i!=one){
                minFirst = HuffmanTree[i].weight;
                two = i;
        }
    }
    TwoMin res;
    res.one = one;
    res.two = two;
    return res;
}
void creatHuffmanTree(int n){// 构造哈夫曼树
    for(int i = 1;i<n;i++){
        TwoMin twoMin = findTwoMin();// 找两个最小的下标 返回的是一个事先定义好的结构体
        int index = ++realSize;
        HuffmanTree[twoMin.one].parent = index;
        HuffmanTree[twoMin.two].parent = index;
        HuffmanTree[index].data = '-';
        HuffmanTree[index].weight = HuffmanTree[twoMin.one].weight + HuffmanTree[twoMin.two].weight;
        HuffmanTree[index].left = twoMin.one;
        HuffmanTree[index].right = twoMin.two;
        HuffmanTree[index].parent = -1;
    }
}
void enCode(char character){// 先找到字符所在的下标 然后判断其是其父亲的左孩子还是右孩子 一次遍历 直至遍历到根节点
    string res = "";
    int index = 1;
    for(int i = 1;i<=realSize;i++){
        if(HuffmanTree[i].data==character){
            index = i;
            break;
        }
    }
    while(HuffmanTree[index].parent!=-1){
        if(HuffmanTree[HuffmanTree[index].parent].left==index)
            res+="0";
        else
            res+="1";
        index = HuffmanTree[index].parent;
    }
    string res_finally = "";
    for(int i = res.length()-1;i>=0;i--){
        res_finally += res[i];
    }
    cout<<character<<": "<<res_finally<<endl;
}
int main(){
    cin>>realSize;// 输入的是初始的字符的个数
    for(int i = 1;i<=realSize;i++){
        cin>>HuffmanTree[i].data;// 字符值
        cin>>HuffmanTree[i].weight;// 字符的权值
    }
    creatHuffmanTree(realSize);
    for(int i = 1;i<=realSize;i++){
        cout<<i<<" "<<HuffmanTree[i].data<<" "<<HuffmanTree[i].weight<<" "<<HuffmanTree[i].parent<<" "<<HuffmanTree[i].left<<" "<<HuffmanTree[i].right<<endl;
    }
    enCode('d');// 输出哈夫曼编码
    return 0;
}



本来昨天晚上就该完成的东西,非得拖到现在完成,真是该死

猜你喜欢

转载自blog.csdn.net/jdq8576/article/details/88923996