hafumanshu.docx

上传人:b****6 文档编号:5884688 上传时间:2023-01-01 格式:DOCX 页数:30 大小:27.13KB
下载 相关 举报
hafumanshu.docx_第1页
第1页 / 共30页
hafumanshu.docx_第2页
第2页 / 共30页
hafumanshu.docx_第3页
第3页 / 共30页
hafumanshu.docx_第4页
第4页 / 共30页
hafumanshu.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

hafumanshu.docx

《hafumanshu.docx》由会员分享,可在线阅读,更多相关《hafumanshu.docx(30页珍藏版)》请在冰豆网上搜索。

hafumanshu.docx

hafumanshu

1

哈夫曼编码 百分之百自己写的 嘿嘿

#include

#include

#define maxsize 20

typedef struct

{

char date,yima[20];

int l,r,next,quan;

}lian,*zhizhen;//备用链表的节点

typedef struct

{

char zifu;//存储输入的字符

int zhixiang;//字符对应在li里面的位置

}jie;//用来存放输入字符的节点

//队

typedef struct xhxb

{

zhizhen xhx;

struct xhxb *next;

}elem,*zhizhend;//队所用的链表的节点

typedef struct

{

zhizhend base;

int size;//队列的当前长度

}dui;//队的标志(只有一个节点)

int xunhuan(zhizhend &head,int l)//创建一个循环链表,head为循环链表的头指针(可以看作),l为循环链表的长度

{

zhizhend p,q;

int i=1;

head=(zhizhend)malloc(sizeof(elem));

if(head==0)return 0;

p=q=head;

while(i

{

q=(zhizhend)malloc(sizeof(elem));

p->next=q;

p=q;

i++;

}

p->next=head;

return 1;

}

int chuangjian(dui &d)//创建一个空队

{

int a;

a=xunhuan(d.base,maxsize);

if(a==0)return 0;

d.size=0;

return 1;

}

int chazhao(dui &d,zhizhend &p)//找到队列的头结点,用p返回其地址值

{

int i=1;

if(d.size==0)return 0;

p=d.base;

while(i<=maxsize-d.size+1)///////

{

p=p->next;

i++;

}

return 1;

}

int jindui(dui &d,zhizhen e)//进队

{

if(d.size>=maxsize)return 0;

d.base=d.base->next;

d.base->xhx=e;

d.size++;

return 1;

}

int chudui(dui &d,zhizhen &e)//出队,用e返回出队元素的值 

{

int a;

zhizhend p;

a=chazhao(d,p);

if(a==0)return 0;

e=p->xhx;

d.size--;

return 1;

}

//队完

int beiyong(zhizhen &li,zhizhen &s)//创建一个备用静态链表 li返回其首地址 并创建一个已用空链表 用s返回其首地址

{

int i;

li=(zhizhen)malloc(256*sizeof(lian));

if(!

li)return 0;

for(i=0;i<255;i++)

{

(li+i)->next=i+1;

(li+i)->l=0;

(li+i)->r=0;

(li+i)->quan=0;/////////////////////////

}

    (li+255)->next=0;

s=li+1;

li->next=s->next;

s->next=0;

return 1;

}

int jmalloc(zhizhen &li,zhizhen &s)//从备用链表中取一个结点放入已用链表s中

{

int p,q;

p=s->next;

s->next=li->next;

q=(li+li->next)->next;

(s+s->next-1)->next=p;

li->next=q;

return 1;

}

int min(int &i,int &j,zhizhen s)//找到链表s中权值最小的两个结点

{

int p;

i=s->next;

j=(s+s->next-1)->next;

p=(s+j-1)->next;

while(p)

{

if((s+p-1)->quan<(s+i-1)->quan||(s+p-1)->quan<(s+j-1)->quan)

{

if((s+p-1)->quan>(s+i-1)->quan)j=p;

else

{

if((s+p-1)->quan>(s+j-1)->quan)i=p;

else

{

if((s+i-1)->quan>(s+j-1)->quan)i=p;

else j=p;

}

}

}

p=(s+p-1)->next;

}

return 1;

}

int jfree(int i,int j,zhizhen &s)//从s中把i,j结点剔除

{

int p=1;

while(p)

{

if((s+p-1)->next==i)(s+p-1)->next=(s+i-1)->next;

p=(s+p-1)->next;

}

p=1;

while(p)

{

if((s+p-1)->next==j)(s+p-1)->next=(s+j-1)->next;

p=(s+p-1)->next;

}

return 1;

}

int hafuman(zhizhen &s,zhizhen &li)//创建一棵霍夫曼树

{

int i,j;

while((s+s->next-1)->next)

{

min(i,j,s);

jmalloc(li,s);

(s+s->next-1)->l=i;

*((s+i-1)->yima)='0';

*((s+i-1)->yima+1)='\0';

        (s+s->next-1)->r=j;

*((s+j-1)->yima)='1';

        *((s+j-1)->yima+1)='\0';

(s+s->next-1)->quan=((s+i-1)->quan+(s+j-1)->quan);

作者:

徐小孩 

  

 

2008-1-2623:

52 

回复此发言 

2

哈夫曼编码 百分之百自己写的 嘿嘿

jfree(i,j,s);

}

return 1;

}

int hebing(zhizhen a,zhizhen b)//把a与b所指向的yima合并 并把所得字符串付给b

{

int i=0,j=0;

char p[20];

while(a->yima[i]!

='\0')

{

p[i]=a->yima[i];

i++;

}

while(b->yima[j]!

='\0')

{

p[i]=b->yima[j];

i++;

j++;

}

j=0;

while(j

{

b->yima[j]=p[j];

j++;

}

b->yima[j]='\0';

return 1;

}

int bianma(zhizhen &s)//编码

{

zhizhen e;

dui d;

int p,i=0;

p=s->next;

    chuangjian(d);

jindui(d,(s+p-1));

while

(1)

{

chudui(d,e);

if(e->l==0)

{

if(d.size==0)break;

continue;

}

        jindui(d,(s+e->l-1));

jindui(d,(s+e->r-1));

if(!

i){i=1;continue;}

hebing(e,(s+e->l-1));

hebing(e,(s+e->r-1));

}

return 1;

}

int zhao(jie *m,int i)//查找数组m中前i-1个元素是否有与m[i]值相等的元素 有返回值为j 否为-1

{

int j;

char c;

c=(m+i)->zifu;

for(j=0;j

{

if((m+j)->zifu==c)return j;

}

return -1;

}

int shuru(jie *m,int &i,zhizhen &s,zhizhen &li,int &len)//字符串的输入,m为字符存储所用链表的首地址,i为字符链表的长度,len为所输入字符中无重复的字符个数

{

i=0;

len=0;

int j;

char c;

beiyong(li,s);

while((c=getchar())!

='\n')

{

(m+i)->zifu=c;

j=zhao(m,i);

if(j!

=-1)

{

(m+i)->zhixiang=(m+j)->zhixiang;

(s+(m+j)->zhixiang-1)->quan++;

}

else

{

jmalloc(li,s);

(m+i)->zhixiang=s->next;

(s+(m+i)->zhixiang-1)->quan++;

(s+(m+i)->zhixiang-1)->date=c;

len++;

}

i++;

}

return 1;

}

void print(jie *m,int i,zhizhen s)//输出编码

{

int j;

for(j=0;j

{

printf("%c ",(m+j)->zifu);

printf("%s     ",(s+(m+j)->zhixiang-1)->yima);

}

printf("\n");

}

int pipei(char *a,char *b)//判断a、b两个字符串是否相等

{

int i=0;

while(*(a+i)!

='\0')

{

if(*(a+i)==*(b+i))i++;

else return 0;

}

if(*(b+i)=='\0')return 1;

return 0;

}

int yima(zhizhen li,char *ma,int len,char &c)//译码

{

int i=0;

zhizhen p;

p=li+2;

while(i<=len)

{

if(pipei(p->yima,ma))

{

c=p->date;

return 1;

}

i++;

p++;

}

return 0;

}

void main()

{

    jie m[50];

int i;//i表征m的长度

int qw,len;

    char ma[20],c;

zhizhen s,li;

printf("请输入一个字符串(字符串中至少有两个不同的字符)\n");

shuru(m,i,s,li,len);

hafuman(s,li);

bianma(s);

printf("其哈夫曼编码为\n");

print(m,i,s);

while

(1)

{

printf("请输入操作\n1、译码   2、退出\n");

scanf("%d",&qw);

if(qw==1)

{

printf("请输入所要翻译的编码\n");

scanf("%s",ma);

if(yima(li,ma,len,c))printf("其对应的字符为%c\n",c);

else printf("输入有错\n");

printf("其哈夫曼编码为\n");

        print(m,i,s);

}

if(qw==2)break;

        if(qw!

=1&&qw!

=2)printf("输入有错\n");

}

}

贪心法求哈夫曼编码

huffman.cpp:

#include

#include

#include"huffman.h"

#defineDN62

#defineSIZE200

voidmain(){

    char*sym="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    chars[SIZE],a[20],c;

    char*d=newchar[5*SIZE];

    cout<<"请输入符号序列:

";

             cin>>s;

    ExtBinTreeh(DN,s,sym);

    h.HuffmanTree();

    inti=0;

    cout<<"编码:

\n";

    while(s[i]!

='\0'){

        cout<

        i++;

    }

    cout<

    intn=i;

    cout<<"各字符出现的频率及码字:

\n";

    int*f=h.GetFr();

    for(i=0;i

        if(f[i]!

=0)

            cout<

'<

    cout<<"输入符号熵:

"<

    cout<<"编码平均码长:

"<

(1)<

    i=0;

    cout<<"译码:

\n";

    while(s[i]!

='\0'){

        if(i==0)d=strcpy(d,h.Coding(s[i]));

        elsed=strcat(d,h.Coding(s[i]));

        i++;

    }

    h.DeCoding(d);

    cout<

}

minheap.h:

templateclassMinHeap{

public:

    MinHeap(intmaxSize);//常成员函数不能修改this指向的内容

    MinHeap(Typearr[],intn);

    ~MinHeap(){delete[]heap;}

    intInsert(constType&x);

    intRemoveMin(Type&x);//用参数作返回值

    TypeDeleteMin();

    intIsEmpty()const{returnCurrentSize==0;}

    intIsFull()const{returnCurrentSize==MaxHeapSize;}

    voidMakeEmpty(){CurrentSize=0;}

private:

    enum{DefaultSize=10};

    Type*heap;

    intCurrentSize;

    intMaxHeapSize;

    voidFilterDown(constintstart,constintend);

    voidFilterUp(intstart);

};

templateMinHeap:

:

MinHeap(intmaxSize){//根据给定大小maxSize,建立堆对象

    MaxHeapSize=DefaultSize

maxSize:

DefaultSize;//确定堆大小

    heap=newType[MaxHeapSize];//创建堆空间

    CurrentSize=0;//初始化

}

templateMinHeap:

:

MinHeap(Typearr[],intn){//根据给定数组中的数据和大小,建立堆对象

    MaxHeapSize=DefaultSize

n:

DefaultSize;

    heap=newType[MaxHeapSize];

    heap=arr;//数组传送

    CurrentSize=n;//当前堆大小

    intcurrentPos=(CurrentSize-2)/2;//最后非叶

    while(currentPos>=0){//从下到上逐步扩大,形成堆

        FilterDown(currentPos,CurrentSize-1);//从currentPos开始,到CurrentSize-1为止,调整

        currentPos--;

    }

}

templateintMinHeap:

:

Insert(constType&x){//在堆中插入新元素x

    if(CurrentSize==MaxHeapSize){//堆满

        cout<<"堆已满"<

        return0;

    }

    heap[CurrentSize]=x;//插在表尾

    FilterUp(CurrentSize);//向上调整为堆

    CurrentSize++;//堆元素增一

    return1;

}

templatevoidMinHeap:

:

FilterUp(intstart){//从start开始,向上直到0,调整堆

    intj=start,i=(j-1)/2;//i是j的双亲

    Typetemp=heap[j];

    while(j>0){

        if(heap[i].root->data.key<=temp.root->data.key)break;

        else{heap[j]=heap[i];j=i;i=(i-1)/2;}

    }

    heap[j]=temp;

}

templatevoidMinHeap:

:

FilterDown(constintstart,constintend){

    inti=start,j=2*i+1;

    Typetemp=heap[i];

    while(j<=end){

        if(jdata.key>heap[j+1].root->data.key)j++;

        if(temp.root->data.key<=heap[j].root->data.key)break;

        else{

            heap[i]=heap[j];

            i=j;

            j=2*j+1;

        }

    }

    heap[i]=temp;

}

templateintMinHeap:

:

RemoveMin(Type&x){

    if(!

CurrentSize){

        cout<<"Heapempty"<

        return0;

    }

    x=heap[0];

    heap[0]=heap[CurrentSize-1];

    CurrentSize--;

    FilterDown(0,CurrentSize-1);

    return1;

}

templateTypeMinHeap:

:

DeleteMin(){//不可以用引用,因为堆扩展时会覆盖返回的元素,引用会出错

    if(!

CurrentSize){

        cout<<"Heapempty"<

        return0;

    }

    Typex=heap[0];

    heap[0]=heap[CurrentSize-1];

    CurrentSize--;

    FilterDown(0,CurrentSize-1);

    returnx;

}

huffman.h:

#include"minheap.h"

#include

templatestructNodeData{

    Typesymbol;//结点代表的符号

    intkey;//记录频数

    charnum;//结点编码

};

templateclassExtBinTree;

templateclassElement{

friendclassExtBinTree;

friendclassMinHeap>;

public:

    Element(Typena='^',intf=0,charn='0'){

        data.key=f;

        data.symbol=na;

        data.num=n;

        parent=leftChild=rightChild=NULL;

    }

private:

    NodeDatadata;

    Element*parent,*leftChild,*r

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 国外设计风格

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1