注册 登录
编程论坛 数据结构与算法

请高手解决一数据结构问题

刘剑龙 发布于 2010-05-20 19:23, 682 次点击
赫夫曼树中,如何判定其左右子树的分界点?例如:已知系统在通信联络中只可能出现八种字符,其概率分别是 0.05 ,0.29 ,0.07, 0.08, 0.14, 0.23, 0.03, 0.11,试设计赫夫曼编码。
希望能给出赫夫曼树的示意图,并给出一定的理由,谢谢先了!
5 回复
#2
2010-05-21 05:39
你是说如何构造赫夫曼树吗?取各字符出现概率的倒数就可以当做权值,然后就按书上的方法构造最优二叉树。
不会画示意图。。。。
#3
刘剑龙2010-05-21 11:41
但是书上的不全是这样啊,我看了赫夫曼树的构造,他是将最小的两个数作为左右子树构造一个新的二叉树,并置新的二叉树的根结点为其左右子树之和,这样的话应该可以只有一种形式啊,怎么书上的和我想的不一样呢,这是什么原因?
#4
寒风中的细雨2010-05-22 11:53
在编程序的时候 不同的构造方法得到的编码可能不同 树的形态也可能有差异(两个最小值左右孩子选一种) 但是最小WPL一定是相同的 编码的结果都应该是前缀码

直接用出现的概率就可以  因为在编程序时一般采用权值和概率是正相关 权值大的出现的概率高 路径就短 编码就短
#include <stdio.h>
#include <stdlib.h>

#define LEN  sizeof(struct HTNode)
#define STACK_INIT_SIZE 10
#define ADD 10
#define F f//输入和输出的格式

typedef float *Welem;//
typedef float Telew;//权重类型表示

typedef struct HTNode
{
    Telew weight;
    int parent, lchild, rchild;
}HTNode;

typedef struct
{
    HTNode *data;
    int n;// the numbers of you need change
}HuffmanTree;
//////////////////////////////////////////////////////////////////
typedef struct
{
    char *top;
    char *base;
    int stacksize;
}SqStack;

void Init_Stack(SqStack &s)
{
    s.base = (char *) malloc ( STACK_INIT_SIZE*sizeof(char));
    s.top = s.base;
    s.stacksize = STACK_INIT_SIZE;
}

void Pop( SqStack &s )
{
    if(s.base!=s.top)
        printf("%c",*--s.top);
}

void Push( SqStack &s, char temp )
{
    if(s.top - s.base >= s.stacksize)
    {
        s.base = (char *) realloc (s.base,(s.stacksize+ADD)*sizeof(char));
        s.top = s.stacksize + s.base;
        s.stacksize += ADD;
    }
    *s.top++ = temp;
}
////////////////////////////////////////////////////////////////////////
//获取有多少个字符需要编码
void Get_N( HuffmanTree &HT )
{
    printf("Input the numbers of you need change:");
    scanf("%d", &HT.n);
}
//获取每一个字符的权重
void Get_Weight( HuffmanTree HT, Welem &w )
{
    w = (Telew *) malloc( HT.n*sizeof(Telew));
    int i;
    for( i=0; i<HT.n; ++i )
        scanf("%F", w+i);
}
//选择权重最小的节点
void Select( HuffmanTree &HT, int i, int &temp)
{
    int m = 2*HT.n - 1;
    int j = 1;
    while( j<=m )
    {
        if( HT.data[j].parent==0 && HT.data[j].weight!=0 )
        {
            temp = j;
            break;
        }
        ++j;
    }
    while( j<=m )
    {
        if( HT.data[j].parent==0 && HT.data[j].weight!=0 )
            if(HT.data[temp].weight>HT.data[j].weight)
            {
                temp = temp + j;
                j = temp - j;
                temp = temp - j;
            }
        ++j;
    }
    HT.data[temp].parent = i;
}
//进行编码工作
void HuffmanCoding( HuffmanTree &HT, Welem w)
{
    if( HT.n<=1 )
        return ;
   
    int m = 2*HT.n-1;
    int i = 0, temp1, temp2;
    SqStack s;
    Init_Stack(s);
    HT.data = ( HTNode * ) malloc ((m+1)*LEN);//第零号单元不用
    HTNode *p = HT.data+1;

    for( i=1; i<=HT.n; ++i, ++w, ++p)
    {
        p->weight =  *w;
        p->parent = 0;
        p->lchild = 0;
        p->rchild = 0;
    }
   
    for(; i<=m; ++i, ++p)
    {
        p->weight = 0;
        p->parent = 0;
        p->lchild = 0;
        p->rchild = 0;
    }
    for(i=HT.n+1; i<=m; ++i)
    {//temp 是最小权重的下标
        Select( HT, i, temp1 );
        Select( HT, i, temp2 );
        HT.data[i].lchild = temp1;
        HT.data[i].rchild = temp2;
        HT.data[i].weight = HT.data[temp1].weight + HT.data[temp2].weight;
    }

    int c, f;
    for(i=1; i<=HT.n; ++i)
    {
        c=i;
        f=HT.data[i].parent;
        printf("%F\t", HT.data[i].weight);
        for( ; f!=0; c=f, f=HT.data[f].parent )
            if( HT.data[f].lchild==c )
                Push(s, '0');
            else
                Push(s, '1');
        while(s.base!=s.top)
            Pop(s);
        printf("\n");
    }
}

int main()
{
    HuffmanTree HT;
    Welem w;

    Get_N( HT );
    Get_Weight( HT, w );
    printf("\n");
    HuffmanCoding( HT, w);
   
    return 0;
}

#5
2010-05-22 18:35
两个结点的位置可以有两种啊,一个在左,一个在右就行了啊。
#6
xichong2010-05-22 18:47
只要是最优二叉树其结果即最小WPL一定是相同的,在信息论与编码教材中关于赫夫曼编码问题有“码长方差”的概念,虽然WPL(相当于数学期望),在高中的时候我们就知道当数学期望相同的情况下,考虑方差大小是衡量好坏(即编码效果最理想)的指标。
要让码长方差最小,即让相加后若出现相同的概率,则靠前位置放,数据结构教材上的关于赫夫曼编码算法也是满足方差最小的。
1