哈夫曼树——顺序存储

内容

1、创建一棵哈夫曼树,顺序存储方式
2、可键盘输入叶子结点的权值
3、输出各节点的权值、父母域、左右孩子域

代码

#include<stdio.h>
#include<stdlib.h>
typedef struct
{
    int weight;
    int parent,lchild,rchild;
}HTNode,*HuffmanTree;

void CreateHuffmanTree(HuffmanTree *HT,int n);
int Select(HuffmanTree *HT,int i);

int main()
{
    int i;
    HuffmanTree HT;
    int n;
    printf("请输入哈夫曼树的叶子节点的个数:");
    scanf("%d",&n);
    CreateHuffmanTree(&HT,n);
    for(i=1;i<2*n;i++)		//输出各节点的权值、父母域、左右孩子域
    {
        printf("结点序号%4d\t权重%4d\tparent%4d\tlchild%4d\trchild%4d\t\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
    }
    return 0;
}

/*函数:void CreateHuffmanTree(HuffmanTree *HT,int n)
  作用:构造一棵哈夫曼树
  输入:HuffmanTree数组的首地址和叶子结点的个数n*/
void CreateHuffmanTree(HuffmanTree *HT,int n)
{
    HuffmanTree *T;
    int m;
    int i;
    int s1,s2;
    if(n<=1)
        return;
    m=2*n-1;
    *HT=(HuffmanTree)malloc(sizeof(HTNode)*(m+1));       //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点
    T=HT;
    for(i=1;i<=m;++i)       //将1~m号单元中的双亲、左孩子、右孩子的下标都初始化为0
    {
        (*HT)[i].parent=0;
        (*HT)[i].lchild=0;
        (*HT)[i].rchild=0;
    }
    printf("请输入每个叶子结点的权值:");
    for(i=1;i<=n;i++)       //输入前n个单元中叶子结点的权值
    {
        scanf("%d",&(*HT)[i].weight);
    /*--------------------------初始化工作结束,下面开始创建哈夫曼树---------------------------------------*/
        printf("%d\t",(*HT)[i].weight);
    }
    printf("\n");
    for(i=n+1;i<=m;++i)
    {//通过n-1次的选择、删除、合并来创建哈夫曼树
        s1=Select(T,i-1);
        (*HT)[s1].parent=i;
        s2=Select(T,i-1);
        (*HT)[s2].parent=i;   //得到新结点i,从森林中删除s1、s2,将s1、s2的双亲域由0改为i
        (*HT)[i].lchild=s1;
        (*HT)[i].rchild=s2;   //s1、s2分别作为i的左右孩子
        (*HT)[i].weight=(*HT)[s1].weight+(*HT)[s2].weight;     //i的权值为左右孩子权值之和
    }
}

/*函数:int Select(HuffmanTree *HT,int i)
作用:在[k](1<=k<=i)中选择两个其双亲域为0且权值最小的结点,并返回他们的在HT中的序号的地址,s1,s2
输入:HuffmanTree数组的首地址和在[k](1<=k<=i-1)中选择两个其双亲域为0且权值最小的结点,并返回他们的在HT中的序号*/
int Select(HuffmanTree *HT,int i)
{
    int k,s;
    int MIN=100;
    for(k=1;k<=i;++k)
    {
        if((*HT)[k].parent==0)
        {
            if((*HT)[k].weight<MIN)
            {
                MIN=(*HT)[k].weight;            //找出权重最小的
                s=k;                      //s存放他的序号
            }
        }
    }
    return s;
}

输出

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值