// hufuman3.cpp.cpp : 定义控制台应用程序的入口点。内部代码纯手工实现 #include <iostream> #include<stdlib.h> #include<string.h> using namespace std; typedef struct huTreeNode { char a; struct huTreeNode * rchild; struct huTreeNode * lchild; }NODE,*TYPE; typedef struct QueueNode{ struct huTreeNode * val; int probabliy; struct QueueNode * next; }QUEUENODE, *pQUEUENODE; typedef struct QUEUE{ int size; pQUEUENODE pHead; }*pQUEUE; typedef struct hlTable{ char symbol; char * code; struct hlTable * pNext; }HLTABLE,* pHLTABLE; //队列头指针 struct QUEUE * pQ=(struct QUEUE *)malloc(sizeof(struct QUEUE)); //table 头指针 pHLTABLE pTHead=(pHLTABLE)malloc(sizeof(HLTABLE)); pHLTABLE pTable=pTHead; void initQueue(pQUEUE pQ) { // pQ=(struct QUEUE *)malloc(sizeof(struct QUEUE)); pQ->size=0; // pQUEUENODE head=(pQUEUENODE)malloc(sizeof(QUEUENODE)); pQ->pHead=(pQUEUENODE)malloc(sizeof(QUEUENODE)); pQ->pHead->next=NULL; return ; } void creatQueue(pQUEUE pQ,char inputString,int *probabliy) { pQUEUENODE pQueueNode=(pQUEUENODE)malloc(sizeof(QUEUENODE)); pQueueNode->next=NULL; TYPE node=(TYPE)malloc(sizeof(struct huTreeNode)); node->a =inputString; node->rchild=NULL; node->lchild=NULL; pQueueNode->val=node; pQueueNode->probabliy=probabliy[(int)inputString]; if(pQ->pHead->next==NULL) { pQ->pHead->next=pQueueNode; pQ->pHead->next->next =NULL; } else { //找重复 去重复 pQUEUENODE p=pQ->pHead; while(p->next!=NULL) { if(p->next->val->a==inputString) { return ; } p=p->next; } //入队列 p=pQ->pHead; while(1) { if(p->next !=NULL && pQueueNode->probabliy>p->next->probabliy) { p=p->next; } else { pQueueNode->next=p->next; p->next=pQueueNode; break; } } } pQ->size++; //pQ->pHead=pQueueNode; // printf("%c\n",pQ->pHead ->val->a); return ; } pQUEUENODE outQueue(pQUEUE pQ) { if(pQ->size==0) { printf("队列已空 出队失败"); return NULL; } else { pQUEUENODE p=pQ->pHead->next; pQ->pHead->next=pQ->pHead->next->next; pQ->size--; return p; } } void inQueue(pQUEUE pQ, pQUEUENODE pQueueNode) { pQUEUENODE p; p=pQ->pHead; while(1) { if(p->next !=NULL && pQueueNode->probabliy>p->next->probabliy) { p=p->next; } else { pQueueNode->next=p->next; p->next=pQueueNode; break; } } pQ->size++; return ; } TYPE buildTree(char * inputString) { int i=0; char m; int *probabliy=(int *)malloc(sizeof(int)*256); for(i=0;i<256;i++) { probabliy[i]=0; } i=0; while(inputString[i]!='\0') { probabliy[(int)inputString[i]]++; i++; } initQueue(pQ); i=0; while(inputString[i]!='\0') { m=inputString[i]; creatQueue(pQ,m,probabliy); i++; } //开始建树 while(pQ->size>=2) { pQUEUENODE p1=(pQUEUENODE)malloc(sizeof(QUEUENODE)); TYPE node=(TYPE)malloc(sizeof(NODE)); // huTreeNode * node1=(huTreeNode *)malloc(sizeof(huTreeNode)); // huTreeNode * node2=(huTreeNode *)malloc(sizeof(huTreeNode)); node->rchild =NULL; node->lchild =NULL; node->a ='0'; p1->val=node; pQUEUENODE p=outQueue(pQ); pQUEUENODE q=outQueue(pQ); //node->rchild=node1; p1->val->rchild=q->val; p1->val->lchild=p->val; p1->probabliy=p->probabliy+q->probabliy; //creatQueue(pQ, inputString,probabliy) inQueue(pQ,p1); } TYPE huboot=outQueue(pQ)->val; return huboot; } //遍历 void traversal(TYPE T,pHLTABLE * p,int k,char code[256]) { if(T!=NULL) { if(T->rchild==NULL&&T->lchild==NULL) { code[k]='\0'; pHLTABLE q=(pHLTABLE)malloc(sizeof(HLTABLE)); q->symbol=T->a; q->code=(char *)malloc(sizeof(char)*(strlen(code)+1)); strcpy(q->code,code); q->pNext=NULL; (*p)->pNext=q; (*p)=(*p)->pNext; } else { if(T->rchild!=NULL) { code[k]='0'; traversal(T->rchild,p,k+1,code); } if(T->lchild!=NULL) { code[k]='1'; traversal(T->lchild,p,k+1,code); } } } else { printf("table 为空"); return ; } return; } //建table void buildTable(TYPE L,pHLTABLE * pTHead) { char code[256]; pHLTABLE * p; traversal(L,pTHead,0,code); return; } //enCode定义 void enCode(char * inputString) { pHLTABLE p; p=pTHead->pNext; int i=0,j=0; for(i=0;inputString[i]!='\0';i++) { while(p!=NULL) { if(p->symbol==inputString[i]) { //printf("%c\n",inputString[i]); printf("%s",p->code); break; } else { p=p->pNext; if(p==NULL) { printf("存在陌生字符!\n"); return ; } } } p=pTHead->pNext; } printf("\n"); return ; } //decode定义 void deCode(char * inputString) { int t=strlen(inputString); // printf("%d\n",t); char str[200]; pHLTABLE p; p=pTHead->pNext; int i=0,j=0; while(inputString[i]!='\0') { str[j]=inputString[i]; j++; i++; str[j]='\0'; while(p!=NULL) { if(strcmp(p->code,str)==0) { // printf("ppppp%s\n",str); printf("%c",p->symbol); j=0; // j--; break; } else { p=p->pNext; } if(p==NULL) { break; } } p=pTHead->pNext; } printf("\n"); return ; } //主函数 int main() { //table链表头指针 pTHead->pNext =NULL; //参考数据源 TYPE L=buildTree("abab12340ljiuof56jyrkwe4uii kyerqqw o...,,ddeeeeeuhd%%%*khfuikj,yrkwesdfret567563tyryeydwrtddiiingfryui54874buyiy iu 98\ uyiiy uy7igi09.,;'[]"); buildTable(L,&pTable); cout<<"编码之后为:" <<endl; enCode("khfuikj,yrkwesdfdddffousdfdfshjguky"); cout<<"解码后内容为"<<endl; deCode("0101010111101110010011001010001011100100001111001010011000011100001000000011100000000000000000111001110101001010010000100000001110000000111010000101011110010111011000100010100001"); scanf("%d");//防闪退 return 0; }
哈夫曼编码和解码
猜你喜欢
转载自blog.csdn.net/qq_32445015/article/details/79972105
今日推荐
周排行