贪心算法-哈夫曼编码

哈夫曼编码

#include <iostream>
using namespace std;

typedef struct Node
{
    int data;
    int leftposition;
    int rightposition;
}Node;

void Heap_Character(Node *data,int num,int start)                   //保持小根堆的性质函数
{
    int left=start*2;
    int right=start*2+1;
    int smallest=start;
    if(left<=num&&data[left].data<data[start].data)
    smallest=left;
    else
    smallest=start;
    if(right<=num&&data[right].data<data[smallest].data)
    smallest=right;
    if(smallest!=start)
    {
        int tempdata=data[start].data;
        int templeftposition=data[start].leftposition;
        int temprightposition=data[start].rightposition;
        data[start].data=data[smallest].data;
        data[start].leftposition=data[smallest].leftposition;
        data[start].rightposition=data[smallest].rightposition;
        data[smallest].data=tempdata;
        data[smallest].leftposition=templeftposition;
        data[smallest].rightposition=temprightposition;
        Heap_Character(data,num,smallest);
    }
}

void Built_Heap(Node *data,int num)                                //创建一个小根堆
{
    for(int i=num/2;i>=1;i--)
        Heap_Character(data,num,i);
}

void Haffman(Node *data,int num)
{
    int rear=num;
    while(num!=1)
    {

        //for(int i=1;i<=rear;i++)                                           //打印结果
        //cout<<data[i].data<<" ";
        //cout<<endl;

        int tempdata=data[num].data;                                          //找到最小的节点,移置最后
        int templeftposition=data[num].leftposition;
        int temprightPosition=data[num].rightposition;
        data[num].data=data[1].data;
        data[num].leftposition=data[1].leftposition;
        data[num].rightposition=data[1].rightposition;
        data[1].data=tempdata;
        data[1].leftposition=templeftposition;
        data[1].rightposition=temprightPosition;
        num--;

        //for(int i=1;i<=rear;i++)                                           //打印结果
        //cout<<data[i].data<<" ";
        //cout<<endl;

        Heap_Character(data,num,1);                                        //保持堆性质,以便于找到第二小的节点

        rear++;
        data[rear].data=data[1].data;
        data[rear].leftposition=data[1].leftposition;
        data[rear].rightposition=data[1].rightposition;

        data[1].data=data[num+1].data+data[rear].data;
        data[1].leftposition=num+1;
        data[1].rightposition=rear;

        //for(int i=1;i<=rear;i++)                                           //打印结果
        //cout<<data[i].data<<" ";
        //cout<<endl<<data[1].leftposition<<"  "<<data[1].rightposition<<endl;

        //cout<<"The num is :"<<num<<endl;
        Built_Heap(data,num);

    }
    //cout<<data[num].data;
}

void ProduceCode(Node *tree,int sum,int position,int *code)
{
    if(tree[position].leftposition==-1&&tree[position].rightposition==-1)
    {
        cout<<tree[position].data<<" :";
        for(int i=0;i<sum;i++)
        cout<<code[i];
        cout<<endl;
    }
    else
    {
        code[sum]=0;
        ProduceCode(tree,sum+1,tree[position].leftposition,code);
        code[sum]=1;
        ProduceCode(tree,sum+1,tree[position].rightposition,code);
        sum++;
    }
}
int main()
{
    int data[7]={0,45,13,12,16,9,5};
    int num=6;
    Node *tree=new Node[num*2];
    for(int i=1;i<=num;i++)
    {
        tree[i].data=data[i];
        tree[i].leftposition=-1;
        tree[i].rightposition=-1;
    }
    for(int i=num+1;i<=num*2-1;i++)
    {
        tree[i].leftposition=-1;
        tree[i].rightposition=-1;
    }

    Built_Heap(tree,num);
    Haffman(tree,num);


    cout<<"Code is below:"<<endl;
    int code[10];
    int sum=0;
    ProduceCode(tree,sum,1,code);


    return 0;
}

运行结果:

 

posted @ 2013-04-18 17:30  再见,少年  Views(306)  Comments(2Edit  收藏  举报