自用 霍夫曼 数据结构复习(代码丑陋,慎看)

代码主要问题在于没有处理相同data结点的能力。

        考试时注意:

                1.原来堆排序最后要再颠倒一下;

                2.堆排序的参数n的值需注意;

                3.依代码逻辑写完后检查一下,不要自以为是;

                4.c++数组本身就是指针,不需要引用;

                5.结构体定义记得加分号,每句话写完记得加分号;

希望自己记得考完补充一下代码注释

furthermore,数据结构真的很美且很好玩。

#include<iostream>
#include<unordered_map>


using namespace std;
//霍夫曼树结点
typedef struct Node{
    int data;
    Node*lchild,*rchild;
};

//交换函数
void swap(int&a,int &b){
    int c=a;
    a=b;
    b=c;
}

//堆排序调整
void pileChange(int a [],int n,int i){
    int j;
    int key=a[i];
    for(j=2*i;j<n;j*=2){
        if(j<n-1 && a[j]>a[j+1]) j++;
        if(key<=a[j]) break;
        a[i]=a[j];
        i=j;
    }
    a[i]=key;
}
//堆排序主函数
void pileSort(int a[],int n){
    for(int i=(n-1)/2;i>-1;--i) pileChange(a,n,i);
    // for(int i=0;i<n;++i) cout<<a[i]<<"\n";
    for(int i=n-1;i>0;--i){
        swap(a[0],a[i]);
        pileChange(a,i,0);
    }
    for(int i=0;i<n/2;++i) swap(a[i],a[n-i-1]);
}

//霍夫曼树建立
Node* hofumSort(int a[],char k[],int n,unordered_map<int,char> & Hash){

    unordered_map<int,Node*>Nodemap;
    int b[n];
    Node*p;
    for(int i=0;i<n;++i){
        b[i]=a[i];
        Hash[a[i]]=k[i];
        p=(Node*)malloc(sizeof(Node)); p->lchild=NULL; p->rchild=NULL;
        Nodemap[a[i]]=p; 
    }
    int curN=n-1;//i为第几次选择
    int x1,x2;
    pileSort(b,n);
    // for(int i=0;i<n;++i) cout<<b[i]<<" ";
    // cout<<"\n";
    while (curN>0){
        


        x1=b[0];
        swap(b[0],b[curN]);
        pileChange(b,curN,0);

        x2=b[0];
        b[0]=x1+x2;
        cout<<x1<<" "<<x2<<" "<<x1+x2<<"\n";
        Nodemap[x1+x2]=(Node*)malloc(sizeof(Node));
        Nodemap[x1]->data=x1;Nodemap[x2]->data=x2;Nodemap[x1+x2]->data=x1+x2;

        Nodemap[x1+x2]->lchild=Nodemap[x1];
        Nodemap[x1+x2]->rchild=Nodemap[x2];


        pileChange(b,curN--,0);
    }    
    // for(int i=0;i<n;++i) cout<<Nodemap[b[i]]->data<<" ";
    return Nodemap[b[0]];
}

void order(Node* p,string s,unordered_map<int,string>&Hashcode){
    
    // cout<<p->data<<" ";
    // cout<<s<<"\n";
    
    if(p==NULL) {cout<<"gg"; return;}
    else if(p->lchild==NULL && p->rchild==NULL){
        Hashcode[p->data]=s;
    }else {
        if(p->lchild) order(p->lchild,s+"0",Hashcode);
        if(p->rchild) order(p->rchild,s+"1",Hashcode);
    }
}


int main(){
    int a[]={6,3,1,5,8,7};
    char k[]={'a','b','c','d','e','f'};
    int size=sizeof(a)/sizeof(int);
    pileSort(a,size);
    // for(int i=0;i<size;++i) cout<<a[i];
    
    //字频与字母对应关系
    unordered_map<int,char>Hash;
    //最终编码结果
    unordered_map<int,string>Hashcode;
    //霍夫曼树头节点
    Node* p=hofumSort(a,k,size,Hash);
    //编码并输出结果
    order(p,"",Hashcode);
    for(int i=0;i<size;++i){
        cout<<k[i]<<":"<<Hashcode[a[i]]<<"|";
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值