数据结构-哈夫曼树运行错误 但调试却正确 一直找不成错误

问题描述

哈夫曼树运行错误 但调试却正确 一直找不成错误

估计问题是出在HuffmanCoding 但怎么都找不出来

 #include "stdio.h"
#include "stdlib.h"
#include "string.h"
char alphabet[]={'A','B','C','D'};
typedef struct
{
    int weight;     //权值
    int parent;     //父节点序号
    int left ;
    int right;
}HuffmanTree;

typedef char *HuffmanCode;  //Huffman编码指针
void SelectNode (HuffmanTree *ht,int n,int *bt1,int *bt2)
//从n个节点中选择parent节点为0,权重最小的两个节点
{
    int i;
    HuffmanTree *ht1,*ht2,*t;
    ht1=ht2=NULL;
    for(i=1;i<=n;i++)
    {
        if(!ht[i].parent)               //父节点为空
        {
            if(ht1==NULL)
            {
                ht1=ht+i;               //
                continue;
            }
            if(ht2==NULL)
            {
                ht2=ht+i;
                if(ht1->weight>ht2->weight)
                {
                    t=ht2;
                    ht2=ht1;
                    ht1=t;          //让ht1指向最小节点 ht2指向第二小
                }
                continue;
            }
            if(ht1 &&ht2)
            {
                if(ht[i].weight<=ht1->weight)
                {
                    ht2=ht1;                    //如果还有比ht1更小的则把ht1赋给ht2 ,ht1继续等于最小
                    ht1=ht+i;
                }
                else if(ht[i].weight<ht2->weight){
                    ht2=ht+i;                       //没有比ht1更小的 但有比ht2小的
                }
            }
        }
    }
    if(ht1>ht2){                    //按数组最初的位置排序
        *bt2=ht1-ht;
        *bt1=ht2-ht;
    }
    else
    {
        *bt1=ht1-ht;
        *bt2=ht2-ht;
    }
}
void CreateTree(HuffmanTree *ht,int n,int *w)
{
    int i,m=2*n-1;    //总节点数
    int bt1,bt2;
    if(n<=1)
        return ;
    for(i=1;i<=n;++i)
    {
        ht[i].weight=w[i-1];
        ht[i].parent=0;
        ht[i].left=0;
        ht[i].right=0;
    }
    for(;i<=m;++i)
    {
        ht[i].weight=0;
        ht[i].parent=0;
        ht[i].left=0;
        ht[i].right=0;
    }
    for(i=n+1;i<=m;++i)
    {
        SelectNode(ht,i-1,&bt1,&bt2);
        ht[bt1].parent=i;
        ht[bt2].parent=i;
        ht[i].left=bt1;
        ht[i].right=bt2;
        ht[i].weight=ht[bt1].weight+ht[bt2].weight;
    }
}

void HuffmanCoding(HuffmanTree *ht,int n,HuffmanCode *hc)
{
    char *cd;
    int start,i;
    int current,parent;
    cd=(char*)malloc(sizeof(char)*n);
    cd[n-1]='';
    for(i=1;i<=n;i++)
    {
        start=n-1;
        current=i;                          //获得当前节点序号
        parent=ht[current].parent;          //获得当前节点父亲的序号
        while(parent)           //当父节点不为空
        {
            if(current==ht[parent].left)    //若当前节点是父亲的左节点
                cd[--start]='0';            //字符最后编码为0 注意这个编码是逆序的 最后其实根节点
            else
                cd[--start]='1';
            current=parent;                 //从当前节点向根节点寻找
            parent=ht[parent].parent;
        }
        hc[i-1]=(char*)malloc(sizeof(char*)*(n-start)); //分配保存编码的内存
        strcpy(hc[i-1],&cd[start]);                     //复制生成的编码
    }
    free(cd);
} 

void Encode(HuffmanCode *hc,char *alphabet,char *str,char *code)
{
    int len=0,i=0,j;
    code[0]='';
    while(str[i])
    {
        j=0;
        while(alphabet[j]!=str[i])   //搜索字母在编码表的位置
            j++;
        strcpy(code+len,hc[j]);     //字母在叶节点的编号到根节点的编号全部复制给code
        len=len+strlen(hc[j]);      // 扩大len的长度(也就是节点深度)
        i++;
    }
    code[len]='';
}

void Decode(HuffmanTree *ht,int m,char *code,char *alphabet,char *decode)//解码
{
    int position=0,i,j=0;
    m=2*m-1;
    while(code[position])
    {
        for(i=m;ht[i].left &&ht[i].right;position++ )
        {
            if(code[position]=='0')
                i=ht[i].left;
            else
                i=ht[i].right;
        }
        decode[j]=alphabet[i-1];
        j++;
    }
    decode[j]='';
}
int main()
{
    int i,n=4,m;
    char test[]="DBDBDABDCDADBDADBDADACDBDBD";
    char code[100],code1[100];

    int w[]={5,7,2,13};
    HuffmanTree *ht;
    HuffmanCode *hc;
    m=2*n-1;
    ht=(HuffmanTree *)malloc((m+1)*sizeof(HuffmanTree));
    if(!ht)
    {
        printf("分配内存失败n");
        exit(0);
    }
    CreateTree(ht,n,w);
    HuffmanCoding(ht,n,hc);
    for(i=1;i<=n;i++)
        printf("字母:%c,权重:%d,编码:%sn",alphabet[i-1],ht[i].weight,hc[i-1]);
    Encode(hc,alphabet,test,code);
    printf("n字符串:n%sn转换后:n%sn",test,code);
    Decode(ht,n,code,alphabet,code1);
    printf("n编码:n%sn转换后:n%sn",code,code1);

    return 0;
}

解决方案

我帮你看看~~~~~~~~~~~~·

解决方案二:

简单帮你修改了下。请采纳!

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
char alphabet[]={'A','B','C','D'};
typedef struct
{
    int weight;     //权值
    int parent;     //父节点序号
    int left ;
    int right;
}HuffmanTree;

typedef char *HuffmanCode;  //Huffman编码指针
void SelectNode (HuffmanTree *ht,int n,int *bt1,int *bt2)
//从n个节点中选择parent节点为0,权重最小的两个节点
{
    int i;
    HuffmanTree *ht1,*ht2,*t;
    ht1=ht2=NULL;
    for(i=1;i<=n;i++)
    {
        if(!ht[i].parent)               //父节点为空
        {
            if(ht1==NULL)
            {
                ht1=ht+i;               //
                continue;
            }
            if(ht2==NULL)
            {
                ht2=ht+i;
                if(ht1->weight>ht2->weight)
                {
                    t=ht2;
                    ht2=ht1;
                    ht1=t;          //让ht1指向最小节点 ht2指向第二小
                }
                continue;
            }
            if(ht1 &&ht2)
            {
                if(ht[i].weight<=ht1->weight)
                {
                    ht2=ht1;                    //如果还有比ht1更小的则把ht1赋给ht2 ,ht1继续等于最小
                    ht1=ht+i;
                }
                else if(ht[i].weight<ht2->weight){
                    ht2=ht+i;                       //没有比ht1更小的 但有比ht2小的
                }
            }
        }
    }
    if(ht1>ht2){                    //按数组最初的位置排序
        *bt2=ht1-ht;
        *bt1=ht2-ht;
    }
    else
    {
        *bt1=ht1-ht;
        *bt2=ht2-ht;
    }
}
void CreateTree(HuffmanTree *ht,int n,int *w)
{
    int i,m=2*n-1;    //总节点数
    int bt1,bt2;
    if(n<=1)
        return ;
    for(i=1;i<=n;++i)
    {
        ht[i].weight=w[i-1];
        ht[i].parent=0;
        ht[i].left=0;
        ht[i].right=0;
    }
    for(;i<=m;++i)
    {
        ht[i].weight=0;
        ht[i].parent=0;
        ht[i].left=0;
        ht[i].right=0;
    }
    for(i=n+1;i<=m;++i)
    {
        SelectNode(ht,i-1,&bt1,&bt2);
        ht[bt1].parent=i;
        ht[bt2].parent=i;
        ht[i].left=bt1;
        ht[i].right=bt2;
        ht[i].weight=ht[bt1].weight+ht[bt2].weight;
    }
}

void HuffmanCoding(HuffmanTree *ht,int n,HuffmanCode *hc)
{
    char *cd;
    int start,i;
    int current,parent;
    cd=(char*)malloc(sizeof(char)*n);
    cd[n-1]='';
    for(i=1;i<=n;i++)
    {
        start=n-1;
        current=i;                          //获得当前节点序号
        parent=ht[current].parent;          //获得当前节点父亲的序号
        while(parent)           //当父节点不为空
        {
            if(current==ht[parent].left)    //若当前节点是父亲的左节点
                cd[--start]='0';            //字符最后编码为0 注意这个编码是逆序的 最后其实根节点
            else
                cd[--start]='1';
            current=parent;                 //从当前节点向根节点寻找
            parent=ht[parent].parent;
        }

        hc[i-1]=(char*)malloc(sizeof(char)*(n-start)); //分配保存编码的内存
        strcpy(hc[i-1],&cd[start]);                     //复制生成的编码
    }
    free(cd);
} 

void Encode(HuffmanCode *hc,char *alphabet,char *str,char *code)
{
    int len=0,i=0,j;
    code[0]='';
    while(str[i])
    {
        j=0;
        while(alphabet[j]!=str[i])   //搜索字母在编码表的位置
            j++;
        strcpy(code+len,hc[j]);     //字母在叶节点的编号到根节点的编号全部复制给code
        len=len+strlen(hc[j]);      // 扩大len的长度(也就是节点深度)
        i++;
    }
    code[len]='';
}

void Decode(HuffmanTree *ht,int m,char *code,char *alphabet,char *decode)//解码
{
    int position=0,i,j=0;
    m=2*m-1;
    while(code[position])
    {
        for(i=m;ht[i].left &&ht[i].right;position++ )
        {
            if(code[position]=='0')
                i=ht[i].left;
            else
                i=ht[i].right;
        }
        decode[j]=alphabet[i-1];
        j++;
    }
    decode[j]='';
}
int main()
{
    int i,n=4,m;
    char test[]="DBDBDABDCDADBDADBDADACDBDBD";
    char code[100],code1[100];

    int w[]={5,7,2,13};
    HuffmanTree *ht;
    HuffmanCode *hc;
    m=2*n-1;
    ht=(HuffmanTree *)malloc((m+1)*sizeof(HuffmanTree));
    hc=(HuffmanCode *)malloc((n+1)*sizeof(HuffmanCode));
    if(!ht)
    {
        printf("分配内存失败n");
        exit(0);
    }
    CreateTree(ht,n,w);
    HuffmanCoding(ht,n,hc);
    for(i=1;i<=n;i++)
        printf("字母:%c,权重:%d,编码:%sn",alphabet[i-1],ht[i].weight,hc[i-1]);
    Encode(hc,alphabet,test,code);
    printf("n字符串:n%sn转换后:n%sn",test,code);
    Decode(ht,n,code,alphabet,code1);
    printf("n编码:n%sn转换后:n%sn",code,code1);
    free(hc);
    hc = NULL;
    free(ht);
    ht = NULL;
    return 0;
}

解决方案三:

时间: 2024-12-02 13:23:49

数据结构-哈夫曼树运行错误 但调试却正确 一直找不成错误的相关文章

数据结构哈夫曼树代码怎么写

问题描述 数据结构哈夫曼树代码怎么写 哈夫曼树:输入一串只包含abcdefg8种字符的字符串,统计每种字符出现的次数,并据此创建相应的哈夫曼树. 这怎么写 解决方案 统计字符个数这个简单,你创建一个数组,将每个字符的ascii-'a',得到下标,对应下标+1http://blog.csdn.net/yaoowei2012/article/details/18180769 解决方案二: http://www.cnblogs.com/shiyangxt/archive/2008/12/05/1348

数据结构-----哈夫曼树的构造以及遍历

/* 根据Huffman树的构造原理进行构造 ... 哈夫曼树在编码压缩的领域有很好的应用,利用Huffman进行编码可以保证数据传输 的无二义性 . 但是要注意的是 对于出现频率大的数据我们应该尽量放在离根节点近的地方进行编码 , 出现频率小的数据我们可以放在距离根节点小的地方. 这样可以提高数据的传输效率 . */ #include "stdio.h" #include "malloc.h" ///节点声明 typedef struct node{ node *

数据结构——赫夫曼树

1 基本概念 赫夫曼树(Huffman Tree)又称为最优树,是一类带权路径长度最短的树.本文仅讨论最优二叉树. 树的路径长度是指从树根到树中其余各个结点的路径长度之和.对具有n个结点的二叉树而言,完全二叉树具有最短的树的路径长度. 若在二叉树中,树叶结点带有权值,则有:结点的带权路径长度定义为从树根到该结点之间的路径长度与该结点上所带权值之积. 若树中有n个树叶结点,且每个树叶结点均带有权值,则有:树的带权路径长度定义为树中所有树叶结点的带权路径长度之和,可记为: 有时,也将树的路径长度称为

编码-赫夫曼树出错 ,编译没错 不知道哪里错了运行不了

问题描述 赫夫曼树出错 ,编译没错 不知道哪里错了运行不了 编译没有错误,运行失败 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #define STACK_INIT_SIZE 100//存储空间初始分配量 没分号";" #define STACKINCREMENT 10 //存储空间分配增量 #define TRUE 1 #def

大话数据结构十六:哈夫曼树(最优二叉树)

1. 引子 当前素质教育的背景下,小学的学科成绩都改为了优秀.良好.及格.不及格这样的模糊词语,而不再通报具体的分数. 用代码可以表示如下: if( a < 60 ) System.out.print("不及格"); else if( a < 70 ) System.out.print("及格"); else if( a < 90 ) System.out.print("良好"); else System.out.print(&

数据结构例程——哈夫曼树

本文是数据结构基础系列(6):树和二叉树中第15课时哈夫曼树的例程. #include <stdio.h> #include <string.h> #define N 50 //叶子结点数 #define M 2*N-1 //树中结点总数 //哈夫曼树的节点结构类型 typedef struct { char data; //结点值 double weight; //权重 int parent; //双亲结点 int lchild; //左孩子结点 int rchild; //右孩

怎样打印哈夫曼树,在运行的时候可以看到自己的哈夫曼树?

问题描述 怎样打印哈夫曼树,在运行的时候可以看到自己的哈夫曼树? 怎样将自己构建的哈夫曼树打印出来,运行时能够看到自己的树,用横线个竖线形成的树,求高手解答,有代码的话能不能贴出来看看,学习学习,谢谢! 解决方案 类似这个http://m.blog.csdn.net/blog/xzongyuan/22073619

c++ 数据结构-一个程序,哈夫曼树的构造遍历打印,编码解码,缺少遍历和打印

问题描述 一个程序,哈夫曼树的构造遍历打印,编码解码,缺少遍历和打印 #include #include /* 数组头文件 / #include #define MAX 999 / 定义长度 / typedef struct{ / 定义哈夫曼编码的结构数组 / char data; int weight; / 定义权值 / int parent; int lchild; int rchild; }huffmannode; typedef struct{ / 定义保存哈夫曼结构体 / char b

数据结构-构造哈夫曼树的小问题

问题描述 构造哈夫曼树的小问题 完整程序在这里:http://wenku.baidu.com/view/dde580a9376baf1ffc4fadbf template class HfmTree :public BinaryTree { public: operator T()const { return weight; } T getW(){ return weight; } void putW(const T& x){ weight = x; } void SetNull(){ root