7-2 哈夫曼树的建立

哈夫曼树,即最优树,是带权路径长度最短的树。有着广泛的应用。在解决某些判定问题上,及字符编码上,有着重要的价值。哈夫曼算法: (1)根据给定的N个权值 W1,W2,W3……Wn ,构成N棵二叉树的集合F= T1,T2,T3……Tn ,其中每棵二叉树T1只有一个带权为WI的根结点,其左右子树均空。 (2)在 F中选出两棵根结点权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的权值为其左右子树上的根结点的权值之和。 (3)在F中删除这两棵树,同时将新得到的加到F之中。重复(2)和(3),直至F中只剩一个为止。 请编程序创建一个哈夫曼树。 输入提示: 输入结点的个数和各个结点的权值,建立一个哈夫曼树并且打印出来。

函数接口定义:

数据类型定义:
typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*/

typedef struct 
{
    unsigned int weight ; /* 用来存放各个结点的权值*/
    unsigned int parent, LChild,RChild ; /*指向双亲、孩子结点的指针*/
}HTNode, * HuffmanTree;   /*动态分配数组,存储哈夫曼树*/

需要完成的接口:
void CrtHuffmanTree(HuffmanTree *ht , int *w, int n);
void outputHuffman(HuffmanTree HT, int m);

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*/

typedef struct 
{
    unsigned int weight ; /* 用来存放各个结点的权值*/
    unsigned int parent, LChild,RChild ; /*指向双亲、孩子结点的指针*/
}HTNode, * HuffmanTree;   /*动态分配数组,存储哈夫曼树*/

void select(HuffmanTree *ht,int n, int *s1, int *s2);
void CrtHuffmanTree(HuffmanTree *ht , int *w, int n);
void outputHuffman(HuffmanTree HT, int m);

int main() 
{ 
    HuffmanTree HT; 
    HuffmanCode HC; 
    int *w; 
    int i,n;      // the number of elements; 
    int wei;    // the weight of a element; 
    int m;

    scanf("%d",&n); 
    w=(int *)malloc((n+1)*sizeof(int)); 
    for(i=1;i<=n;i++)
    {
        fflush(stdin);
        scanf("%d",&wei); 
        w[i]=wei; 
    } 

    CrtHuffmanTree(&HT,w,n); 
    m = 2*n-1;
    outputHuffman(HT,m); 

    return 0;    
} 

void select(HuffmanTree *ht,int n, int *s1, int *s2)
{
    int i;
    int min;
    for(i=1; i<=n; i++)
    {
        if((*ht)[i].parent == 0)
        {
            min = i;
            i = n+1;
        }
    }
    for(i=1; i<=n; i++)
    {
        if((*ht)[i].parent == 0)
        {
            if((*ht)[i].weight < (*ht)[min].weight)
                min = i;
        }
    }
    *s1 = min;
    for(i=1; i<=n; i++)
    {
        if((*ht)[i].parent == 0 && i!=(*s1))
        {
            min = i;
            i = n+1;
        }
    }
    for(i=1; i<=n; i++)
    {
        if((*ht)[i].parent == 0 && i!=(*s1))
        {
            if((*ht)[i].weight < (*ht)[min].weight)
                min = i;
        }
    }
    *s2 = min;
}

void outputHuffman(HuffmanTree HT, int m)
{
    if(m!=0)
    {
        printf("%d  ", HT[m].weight);
        outputHuffman(HT,HT[m].LChild);
        outputHuffman(HT,HT[m].RChild);
    }
}

/* 请在这里填写答案 */
void CrtHuffmanTree(HuffmanTree *ht , int *w, int n)
{
}
void outputHuffman(HuffmanTree HT, int m)
{
}

输入样例:

在这里给出一组输入。例如:

4
7
5
2
4

输出样例:

在这里给出相应的输出。例如:

18  7  11  5  6  2  4  

 

接口实现:

void CrtHuffmanTree(HuffmanTree *ht , int *w, int n)
{ /* w存放已知的n个权值,构造哈夫曼树ht */
	int m,i;
	int s1,s2;
	m=2*n-1;
	*ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode));  /*0号单元未使用*/
	for(i=1;i<=n;i++) 
	{/*1-n号放叶子结点,初始化*/
		(*ht)[i].weight = w[i];
		(*ht)[i].LChild = 0;
		(*ht)[i].parent = 0;
		(*ht)[i].RChild = 0;
	}		
	for(i=n+1;i<=m;i++)
	{
		(*ht)[i].weight = 0;
		(*ht)[i].LChild = 0;
		(*ht)[i].parent = 0;
		(*ht)[i].RChild = 0;
	}    /*非叶子结点初始化*/
/*	------------初始化完毕!对应算法步骤1---------*/
	
	for(i=n+1;i<=m;i++)    /*创建非叶子结点,建哈夫曼树*/
	{  /*在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2返回*/
		select(ht,i-1,&s1,&s2);
		(*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;
	} 
}/*哈夫曼树建立完毕*/
void outputHuffman(HuffmanTree HT, int m)
{
	if(m!=0)
	{
		printf("%d  ", HT[m].weight);
		outputHuffman(HT,HT[m].LChild);
		outputHuffman(HT,HT[m].RChild);
	}
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值