哈夫曼树的构造

该代码实现了一个C++程序,用于创建和显示Huffman树。程序首先通过快速排序对权值进行排序,然后使用这些权值构建Huffman树。在构建过程中,它维护一个队列来存储节点,并不断合并最小的两个节点以生成新的父节点。最后,程序输出构建的Huffman树及其权重信息。
摘要由CSDN通过智能技术生成

#include <iostream>
#include <queue>
#include <algorithm>

using namespace std;
typedef struct
{
    char data;                     /*字符*/                    
    int weight;                 /* 结点的权值*/
    int parent;                 /* 双亲的下标*/
    int LChild;                 /* 左孩子结点的下标*/
    int RChild;                 /* 右孩子结点的下标*/
} HTNode, *HuffmanTree; /* HuffmanTree 是一个结构数组类型,0 号单元不 用。 */  //int Hnode int* HUffmanTree

queue<int> qu;

void Mysort(HTNode*HT,int num,int &s1,int &s2,int loop_num){
    int arr[num] = {0}; // arr[num-1] arr[num-2] arr[0] arr[num]
    int i = 0;
    
    while(!qu.empty()){
        arr[i++] = qu.front();
        qu.pop();        
    } //arr[1] arr[2] arr[3] arr[4] arr[5] arr[6]

    // 使用快速排序对数组进行排序
    sort(arr, arr + num);
    // 将排序后的数字重新添加到队列中
    i = 0;
    for(;i<num;i++){
        qu.push(arr[i]);
    }
    
    for(int k=1;k<=2;k++){
        int min = qu.front();
        qu.pop(); //这里可以看出 num 每一次进Mysort函数都会减1,弹出2次,再push一次,size就会减小.(队列qu是全局变量,所以函数里面也会改变) 
        //int min_2 = qu.front();
        for(int j=1;j<=loop_num;j++){ //loop_num表示现在树中所有的节点数量,min表示队列中存在的最小值,而非整个树中 
            if(min == HT[j].weight){//HT[loop_size].weight HT[7].weight
                if(k == 1){
                    s1 = j;        
                    break;    
                }
                //是为了防止最小值中出现min_1 = min_2的,作业中便存在这种情况 
                else if(k == 2 && s1 == j){
                    continue;
                }
                else if(k == 2 && s1 != j){
                    s2 = j;
                    break;
                }
            }
        }
        
    }    
}

void CreateHuffmanTree(HuffmanTree HT,int n,int m){
    int s1 = 1,s2 = 1;
    //所有结点的初始化
    for(int i=1;i<=m;i++){
        HT[i].LChild = 0; HT[i].RChild = 0;HT[i].parent = 0;
    }
    
    //初始化char(data)-可有可无 
    cout<<"依次输入每一个结点的字符"<<endl;
    for(int i=1;i<=n;i++){
        cin>>HT[i].data;
    }
    
    //初始化权值
    cout<<"依次输入每一个结点的权值"<<endl;
    for(int i=1;i<=n;i++){
        cin>>HT[i].weight;
        qu.push(HT[i].weight);
    }
    
    int i = n + 1;//n表示最开始有n个叶子节点 
    int loop_num = n; 
    int size = qu.size();
    
    for(;i<=m;i++){//m表示整个哈夫曼树有m个节点,m=2*n-1 
        Mysort(HT,size,s1,s2,loop_num++);//loop_num的作用是 每次计算出新的双亲节点后 总节点数量. 
        HT[s1].parent = i;
        HT[s2].parent = i;
        HT[i].LChild = s1;
        HT[i].RChild = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;
        qu.push(HT[i].weight); 
        size = qu.size();//应结合Mysort函数中的内容,size每次循环都会减1,二路归并思想 
    }//HT[9].weight HT[10].weight HT[11].weight HT[12].weight HT[13].weight
}

void DispHuffmanTree(HuffmanTree HT,int index){
    cout<<"哈夫曼树如下:"<<endl;
    cout<<"weight"<<'\t'<<"lchild"<<'\t'<<"rchild"<<'\t'<<"parent"<<endl;
    for(int i=1;i<=index;i++){
        cout<<HT[i].weight<<'\t'<<HT[i].LChild<<'\t'<<HT[i].RChild<<'\t'<<HT[i].parent<<endl;
    }
    cout<<"带权路径长度WPL:" <<endl;
    cout<<HT[index].weight;
}

int main(){
    int n = 6;
    int m = 2*n-1;
    HuffmanTree HT=new HTNode[m+1];
    CreateHuffmanTree(HT,n,m);
    DispHuffmanTree(HT,m);
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值