程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程綜合問答 >> 編碼-赫夫曼樹出錯 ,編譯沒錯 不知道哪裡錯了運行不了

編碼-赫夫曼樹出錯 ,編譯沒錯 不知道哪裡錯了運行不了

編輯:編程綜合問答
赫夫曼樹出錯 ,編譯沒錯 不知道哪裡錯了運行不了

編譯沒有錯誤,運行失敗


#include <stdio.h>
#include <stdlib.h>
#include <math.h> 
#include <string.h> 
#define STACK_INIT_SIZE 100//存儲空間初始分配量  沒分號“;” 
#define STACKINCREMENT 10 //存儲空間分配增量

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1

typedef struct {
    unsigned int weight;
    unsigned int parent,lchild,rchild;  
}HTNode,*HuffmanTree;

typedef char **HuffmanCode;

//在HT[1..i-1]選擇parent為0且weight最小的兩個結點,
//其序號為最小s1和次小s2(若parent≠0,則說明被選取過不能再選)
//s1s2並不是指的weight權值,而是最(次)小的這個字符前面的編號(後面需要填進lchild、rchild)

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


void HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int *w,int n){
    //n字符 m節點 HT空間
    int m,i;
    HuffmanTree p;
    //int w[8] = {5,29,7,8,14,23,3,11};
    m = 2*n-1;
    if(n<=1){return;}   
    //加上一個未用的0號單元
    HT = (HuffmanTree *)malloc((m+1)*sizeof(HTNode)); 

    //一:初始化,得a圖:
    //(1)把已有字符(1-8) 權重賦值w,左右孩子及parent賦值為0,p指向第二個單元(非0第一個) 
    for(p=*HT+1,i=1 ; i<=n ; ++i,++p,++w){//[問題p=HT+1?]看和鴻昌的聊天記錄 
        //*p={*w,0,0,0};
        //錯誤原因: 賦值數組不能分著寫
        //http://zhidao.baidu.com/link?url=jZOgI5PGVycg1v6c1pJ2AlDI3J6fiDLUQQ-1FkGjGzrXTE-hYQusYkoVQlM-EBhr3IjdF9d1wy-o_6elz6m2hald8u0LVM1EUzDaTZ6Rs7e
        (*p).weight = *w;
        (*p).parent = 0;
        (*p).lchild = 0;
        (*p).rchild = 0;
    }
    //(2)把未知字符(9-15) 權重、左右孩子及parent賦值為0, p指向上面跳出來的 未知字符的第一個 9
    for(;i<=m;++i,++p){
        (*p).weight = 0;
        (*p).parent = 0;
        (*p).lchild = 0;
        (*p).rchild = 0;    
    }

    //二:建立赫夫曼樹,得到b圖 
    //在HT[1..i-1]選擇parent為0且weight最小的兩個結點,其序號為最小s1和次小s2(若parent≠0,則說明被選取過不能再選)
    for(i=n+1;i<=m;++i){    //n+1 即後面未知字符 (比如9開始到15) 
    int s1,s2;
    //void Select(HuffmanTree HT,int q,int *s1,int *s2){
    Select(*HT,i-1,&s1,&s2);

    //select(*HT,i-1,&s1,&s2);

    //給s1 s2的parent賦值為當前i 編號 
    (*HT)[s1].parent = i;
    (*HT)[s2].parent = i;
    //給當前i 的lchild和rchild賦值為s1、s2編號 ,給當前i 的 weight賦值為二者權重之和
    //設最小的作左子樹,次小的作右子樹 
    (*HT)[i].lchild = s1;
    (*HT)[i].rchild = s2;
    (*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
    }

    //三:從葉子到根逆向求每個結點字符的赫夫曼編碼 

    //存放赫夫曼編碼的cd 
    char cd[n];
    int c,f;
    //分配n個字符編碼的頭指針向量HC 
    //HuffmanTree HC;報錯類型:declaration of'HTNode* HC'shadows a parameter 原因:函數參數裡已有HC的定義導致重復 
    HC = (HuffmanCode *)malloc((n+1)*sizeof(char *));
    //編碼結束符  如聲明cd[8],0-7中最後一個結束符則為cd[7] 
    cd[n-1] = '\0';//書上寫錯了,應該是'\0' 
    //1-8逐個求 
    for(i=1;i<=n;++i){
        //編碼結束符位置 
        int start = n-1;
        //c=i,f指向當前字 符i的雙親 雙親不為0則循環 經過循環一次後,當前字符變成它的雙親,以此逆向遞推 
        //小細節:--start  如圖 
        for(c=i,f=(*HT)[i].parent;f!=0;c=f,f=(*HT)[f].parent){
            if((*HT)[f].lchild ==c){
            cd[--start]='0';//書上寫錯了,應該是單引號'0' 
            }else{
            cd[--start]='1';
            }
            //for循環結束後,得到cd,為第i個字符分配存儲空間HC
            (*HC)[i] = (char *)malloc((n-start)*sizeof(char));
            //start目前指到最前面了,所以將cd復制(strcpy)給HC 
            /*原型聲明:char *strcpy(char* dest, const char *src);
                頭文件:#include <string.h> 和 #include <stdio.h>
                功能:把從src地址開始且含有NULL結束符的字符串復制到以dest開始的地址空間*/
            strcpy((*HC)[i],&cd[start]);
        }
    }
    free(cd);
}




int main(void){
   HuffmanTree HT;
   HuffmanCode HC;
   int n;
   printf("請輸入字符個數(空格間隔):");
   scanf("%d",&n);

   int i; 
   int *w=NULL;
   w=(int*)malloc(n*sizeof(int));
   printf("請依次輸入權值(空格間隔):");
   for(i=0;i<n;i++){
      scanf("%d",w+i);
   }

   HuffmanCoding(&HT,&HC,w,n);
   for(i=1;i<=n;i++){ 
   puts(HC[i]);//???
   } 
}

已解決。。。

最佳回答:


你用寫的?
char cd[n];
這句能通過編譯?怎麼可能?

baidu_29435963
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved