数据结构——哈夫曼树

一.相关概念

1.叶子结点的权值:

通常表示该结点的访问次数

2.哈夫曼树:

给定一组有确定权值的叶子结点,带权路径长度最小的二叉树。

3.哈夫曼树的特点:

1.权值越大的叶子结点越靠近根节点,权值越小的叶子结点越远离根节点。

2.只有度为0和度为2的结点。

4.哈夫曼算法基本思想:

(1)初始化:

由给定的 n个权值构造n棵只有一个根结点的二叉树,从而得到一个二叉树集合。

(2)选取与合并:

在二叉树集合中选取根节点的权值最小的两颗二叉树分别作为左、右子树构造一颗新的二叉树,这颗新的二叉树的根结点的权值为其左、右子树根结点的权值之和。

(3)删除与加入

在二叉树集合中删去作为左、右子树的二叉树,并将新建立的二叉树加入到二叉树结合中。

(4)重复

重复(2)(3)两步,直到二叉树集合中只剩下一颗二叉树。

二.哈夫曼算法的存储结构

struct element{
    int weight;
    int lchild,rchild,parent;
};

 设置一个数组 huffTree[2n-1]

三.伪代码

1.数组huffTree初始化

所有元素结点的双亲、左右孩子都置为-1.

2.给定权值

数组huffTree的前n个元素的权值给定

3.进行n-1次合并

3.1 在二叉树集合中选取两个权值最小的根结点,其下标为i1,i2

3.2 将二叉树i1,i2合并为一棵新的二叉树

四.代码实现

//哈夫曼树
#include <iostream>

using namespace std;

struct element{
    int weight;
    int lchild,rchild,parent;
};

void select(element hufftree[],int k,int &i1,int &i2){
    for(int i=0;i<k;i++){//先初始化i1,i2
        if(hufftree[i].parent==-1){
            i1=i2=i;
            break;
        }
    }
    for(int i=0;i<k;i++){
        if(hufftree[i].parent==-1&&hufftree[i].weight<hufftree[i1].weight){
            i1=i;
        }
    }
    for(int i=0;i<k;i++){
        if(hufftree[i].parent==-1&&hufftree[i].weight<hufftree[i2].weight&&i!=i1){
            i2=i;
        }
    }
    cout<<"最小下标"<<i1<<"次小下表"<<i2<<endl;
}

void huffmanTree(element hufftree[],int w[],int n){
    int i1,i2;
    for(int i=0;i<2*n-1;i++){//初始化
        hufftree[i].parent=-1;
        hufftree[i].lchild=-1;
        hufftree[i].rchild=-1;
    }
    for(int i=0;i<n;i++){//权值初始化
        hufftree[i].weight=w[i];
    }
    for(int k=0;k<2*n-1;k++){
        select(hufftree, k, i1, i2);
        hufftree[k].weight=hufftree[i1].weight+hufftree[i2].weight;
        hufftree[i1].parent=k;
        hufftree[i2].parent=k;
        hufftree[k].lchild=i1;
        hufftree[k].rchild=i2;
    }
}

int main(int argc, const char * argv[]) {
    int n,*w;
    cout<<"请输入结点个数:"<<endl;
    cin>>n;
    const int x=n;
    w=new int[x];
    element *huffTree=new element[x];
    cout<<"请输入"<<n<<"个权值:"<<endl;
    huffmanTree(huffTree, w, n);
    cout<<"打印构建好的哈夫曼树数组下标"<<endl;
    cout<<"weight\t"<<"parent\t"<<"lchild\t"<<"rchild\t"<<endl;
    for(int i=0;i<n;i++){
        cout<<huffTree[i].weight<<"\t";
        cout<<huffTree[i].parent<<"\t";
        cout<<huffTree[i].lchild<<"\t";
        cout<<huffTree[i].rchild<<"\t";
        cout<<endl;
    }
    delete []w;
    delete []huffTree;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值