MOOC Zhejiang University Data Structure-05-Tree 9 Códigos Huffman (30 puntos)

Consulte el registro de error escrito por los códigos Huffman del árbol 05 9 (30 puntos)
:
1. El código de inserción y eliminación del montón no es muy hábil

void Insert(pHeap H,struct TreeNode T){
    
    
    int i = ++H->size;
    for(;T.weight < H->Data[i/2].weight;i/=2){
    
    //wrong used T.weight < H->Data[i].weight
        H->Data[i] = H->Data[i/2];
    }
    H->Data[i] = T;
}
Tree Delete(pHeap H){
    
    
    int parent,child;
    Tree T = CreateTree(); //wrong used Tree T = H->Data[1];
    *T = H->Data[1];
    struct TreeNode temp = H->Data[H->size--]; //Tree temp = &(H->Data[H->size--]);
    for(parent=1;2*parent <= H->size;parent=child){
    
    //wrong used temp.weight>H->Data[parent].weight
        child = 2*parent;
        if(child!=H->size && H->Data[child].weight > H->Data[child+1].weight) child++;//wrong used H->size!=64
        if(temp.weight < H->Data[child].weight) break;
        H->Data[parent] = H->Data[child];//我在这里多加了一个else 应该也不影响吧
    }
    H->Data[parent] = temp; 
    return T;
}

2. El establecimiento del árbol Huffman no es muy hábil

Tree Huffman(pHeap H){
    
    
    Tree T;
    T = CreateTree();
    while(H->size!=1){
    
    
        T->left = Delete(H);
        T->right = Delete(H);
        T->weight = T->left->weight+T->right->weight;
        Insert(H,*T);
    }
    T = Delete(H);//forget this sentence necessary????
    return T;
}

3. Búsqueda recursiva de WPL

int WPL(Tree T,int depth){
    
    
    if(T->left==NULL&&T->right==NULL){
    
     //当此节点为叶子节点是
        return depth*T->weight;
    }
    else{
    
    //在哈夫曼树中,当此节点不是叶子结点时,此节点必然有两个子节点
        return WPL(T->left,depth+1)+WPL(T->right,depth+1);
    }
}
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
int cnt0,cnt2,N;
int w[64],codelen;
char ch[64];
typedef struct TreeNode *Tree;
struct TreeNode{
    
    
    int weight;
    Tree left,right;
};
typedef struct Heap *pHeap;
struct Heap{
    
    //借助堆建立哈夫曼树
    struct TreeNode Data[64];
    int size;
};
pHeap CreateHeap(){
    
    
    pHeap H;
    H = (pHeap)malloc(sizeof(struct Heap));
    H->size=0;//wrong used H->size=1;
    H->Data[0].weight=-1;//哨兵?
    return H;
}
Tree CreateTree(){
    
    //建立一个树结点
    Tree T;
    T = (Tree)malloc(sizeof(struct TreeNode));//wrong used 64*sizeof(struct TreeNode)
    T->weight = 0;//why 0?
    T->left = T->right = NULL;
    return T;
}
void Insert(pHeap H,struct TreeNode T){
    
    
    int i = ++H->size;
    for(;T.weight < H->Data[i/2].weight;i/=2){
    
    //wrong used T.weight < H->Data[i].weight
        H->Data[i] = H->Data[i/2];
    }
    H->Data[i] = T;
}
Tree Delete(pHeap H){
    
    
    int parent,child;
    Tree T = CreateTree(); //wrong used Tree T = H->Data[1];
    *T = H->Data[1];
    struct TreeNode temp = H->Data[H->size--]; //Tree temp = &(H->Data[H->size--]);
    for(parent=1;2*parent <= H->size;parent=child){
    
    //wrong used temp.weight>H->Data[parent].weight
        child = 2*parent;
        if(child!=H->size && H->Data[child].weight > H->Data[child+1].weight) child++;//wrong used H->size!=64
        if(temp.weight < H->Data[child].weight) break;
        H->Data[parent] = H->Data[child];//我在这里多加了一个else 应该也不影响吧
    }
    H->Data[parent] = temp; 
    return T;
}
Tree Huffman(pHeap H){
    
    
    Tree T;
    T = CreateTree();
    while(H->size!=1){
    
    
        T->left = Delete(H);
        T->right = Delete(H);
        T->weight = T->left->weight+T->right->weight;
        Insert(H,*T);
    }
    T = Delete(H);//forget this sentence necessary????
    return T;
}
int WPL(Tree T,int depth){
    
    
    if(T->left==NULL&&T->right==NULL){
    
     //当此节点为叶子节点是
        return depth*T->weight;
    }
    else{
    
    //在哈夫曼树中,当此节点不是叶子结点时,此节点必然有两个子节点
        return WPL(T->left,depth+1)+WPL(T->right,depth+1);
    }
}
void CountNode(Tree T){
    
    
    if(T){
    
    
        if(T->left&&T->right) cnt2++;
        else if(!T->left&&!T->right) cnt0++;
        else cnt0=0;//这一步有点怪
        CountNode(T->left);
        CountNode(T->right);
    }
}
int judge(){
    
    
    int i,j,wgh,flag=1;
    char s1[64],s2[64];
    Tree T = CreateTree(),pt=NULL;
    for(i=0;i<N;++i){
    
    //对每一行
        scanf("%s %s",s1,s2);
        if(strlen(s2) > N) return 0;
        pt = T;
        for(j=0;s1[0]!=ch[j];++j);//wrong used s1!=ch[j]
        wgh = w[j];
        for(j=0;s2[j];++j){
    
    //wrong used !s2[j]
            //对一个字母的编码进行判断 
            if(s2[j]=='0'){
    
    
                if(!pt->left) pt->left=CreateTree();
                pt = pt->left;//这个else是真的不该写
            }
            if(s2[j]=='1'){
    
    
                if(!pt->right) pt->right=CreateTree();
                pt = pt->right;
            }
            if(pt->weight) flag = 0;
            if(!s2[j+1]){
    
    
                if(pt->left||pt->right) flag=0;
                pt->weight=wgh;//多写了else
            }
        }
    }
    if(!flag) return 0;
    cnt0=cnt2=0;
    CountNode(T);
    if(cnt0 != cnt2+1) return 0;
    if(codelen == WPL(T,0)) return 1;
    else return 0;
}
int main(){
    
    
    int i,n;//我就因为这里多定义了N答案就错了???
    Tree T=CreateTree();//忘记初始化
    pHeap H=CreateHeap();
    scanf("%d",&N);
    for(i=0;i<N;++i){
    
    //建立堆来为建立哈夫曼树做准备
        getchar();
        scanf("%c %d",&ch[i],&w[i]);
        H->Data[H->size].left = H->Data[H->size].right = NULL;//forget this sentence
        T->weight = w[i];
        Insert(H,*T);
    }
    T = Huffman(H);
    codelen = WPL(T,0);//忘记传入参数0
    scanf("%d",&n);
    while(n--){
    
    
        if(judge()) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43919570/article/details/105552894
Recomendado
Clasificación