压缩代码非常简单.docx
- 文档编号:531816
- 上传时间:2022-10-10
- 格式:DOCX
- 页数:14
- 大小:18.21KB
压缩代码非常简单.docx
《压缩代码非常简单.docx》由会员分享,可在线阅读,更多相关《压缩代码非常简单.docx(14页珍藏版)》请在冰豆网上搜索。
压缩代码非常简单
压缩代码非常简单,首先用ASCII值初始化511个哈夫曼节点:
CHuffmanNodenodes[511];
for(intnCount=0;nCount<256;nCount++)
nodes[nCount].byAscii=nCount;
然后,计算在输入缓冲区数据中,每个ASCII码出现的频率:
for(nCount=0;nCount nodes[pSrc[nCount]].nFrequency++; 然后,根据频率进行排序: qsort(nodes,256,sizeof(CHuffmanNode),frequencyCompare); 现在,构造哈夫曼树,获取每个ASCII码对应的位序列: intnNodeCount=GetHuffmanTree(nodes); 构造哈夫曼树非常简单,将所有的节点放到一个队列中,用一个节点替换两个频率最低的节点,新节点的频率就是这两个节点的频率之和。 这样,新节点就是两个被替换节点的父节点了。 如此循环,直到队列中只剩一个节点(树根)。 //parentnode pNode=&nodes[nParentNode++]; //popfirstchild pNode->pLeft=PopNode(pNodes,nBackNode--,false); //popsecondchild pNode->pRight=PopNode(pNodes,nBackNode--,true); //adjustparentofthetwopopednodes pNode->pLeft->pParent=pNode->pRight->pParent=pNode; //adjustparentfrequency pNode->nFrequency=pNode->pLeft->nFrequency+pNode->pRight->nFrequency; 这里我用了一个好的诀窍来避免使用任何队列组件。 我先前就直到ASCII码只有256个,但我分配了511个(CHuffmanNodenodes[511]),前255个记录ASCII码,而用后255个记录哈夫曼树中的父节点。 并且在构造树的时候只使用一个指针数组(ChuffmanNode*pNodes[256])来指向这些节点。 同样使用两个变量来操作队列索引(intnParentNode=nNodeCount;nBackNode=nNodeCount–1)。 接着,压缩的最后一步是将每个ASCII编码写入输出缓冲区中: intnDesIndex=0; //looptowritecodes for(nCount=0;nCount { *(DWORD*)(pDesPtr+(nDesIndex>>3))|= nodes[pSrc[nCount]].dwCode<<(nDesIndex&7); nDesIndex+=nodes[pSrc[nCount]].nCodeLength; } (nDesIndex>>3): >>3以8位为界限右移后到达右边字节的前面 (nDesIndex&7): &7得到最高位. 注意: 在压缩缓冲区中,我们必须保存哈夫曼树的节点以及位序列,这样我们才能在解压缩时重新构造哈夫曼树(只需保存ASCII值和对应的位序列)。 解压缩 解压缩比构造哈夫曼树要简单的多,将输入缓冲区中的每个编码用对应的ASCII码逐个替换就可以了。 只要记住,这里的输入缓冲区是一个包含每个ASCII值的编码的位流。 因此,为了用ASCII值替换编码,我们必须用位流搜索哈夫曼树,直到发现一个叶节点,然后将它的ASCII值添加到输出缓冲区中: intnDesIndex=0; DWORDnCode; while(nDesIndex { nCode=(*(DWORD*)(pSrc+(nSrcIndex>>3)))>>(nSrcIndex&7); pNode=pRoot; while(pNode->pLeft) { pNode=(nCode&1)? pNode->pRight: pNode->pLeft; nCode>>=1; nSrcIndex++; } pDes[nDesIndex++]=pNode->byAscii; } 过程 #include #include #include #include #include #defineM10 typedefstructFano_Node { charch; floatweight; }FanoNode[M]; typedefstructnode { intstart; intend; structnode*next; }LinkQueueNode; typedefstruct { LinkQueueNode*front; LinkQueueNode*rear; }LinkQueue; voidEnterQueue(LinkQueue*q,ints,inte) { LinkQueueNode*NewNode; NewNode=(LinkQueueNode*)malloc(sizeof(LinkQueueNode)); if(NewNode! =NULL) { NewNode->start=s; NewNode->end=e; NewNode->next=NULL; q->rear->next=NewNode; q->rear=NewNode; } elseprintf("Error! "); } //***按权分组***// voidDivide(FanoNodef,ints,int*m,inte) { inti; floatsum,sum1; sum=0; for(i=s;i<=e;i++) sum+=f.weight; *m=s; sum1=0; for(i=s;i { sum1+=f.weight; *m=fabs(sum-2*sum1)>fabs(sum-2*sum1-2*f.weight)? (i+1): *m; if(*m==i) break; } } main() { inti,j,n,max,m,h[M]; intsta,mid,end; floatw; charc,fc[M][M]; FanoNodeFN; LinkQueueNode*p; LinkQueue*Q; //***初始化队Q***// Q->front=(LinkQueueNode*)malloc(sizeof(LinkQueueNode)); Q->rear=Q->front; Q->front->next=NULL; printf("\t***FanoCoding***\n"); printf("Pleaseinputthenumberofnode: ");/*输入信息*/ scanf("%d",&n); i=1; while(i<=n) { printf("%dweightandnode: ",i); scanf("%f%c",&FN.weight,&FN.ch); for(j=1;j { if(FN.ch==FN[j].ch) { printf("Samenode! ! ! \n"); break; } } if(i==j) i++; } for(i=1;i<=n;i++)/*排序*/ { max=i+1; for(j=max;j<=n;j++) max=FN[max].weight j: max; if(FN.weight { w=FN.weight; FN.weight=FN[max].weight; FN[max].weight=w; c=FN.ch; FN.ch=FN[max].ch; FN[max].ch=c; } } for(i=1;i<=n;i++)/*初始化h*/ h=0; EnterQueue(Q,1,n);/*1和n进队*/ while(Q->front->next! =NULL) { p=Q->front->next;/*出队*/ Q->front->next=p->next; if(p==Q->rear) Q->rear=Q->front; sta=p->start; end=p->end; free(p); Divide(FN,sta,&m,end);/*按权分组*/ for(i=sta;i<=m;i++) { fc[h]='0'; h++; } if(sta! =m) EnterQueue(Q,sta,m); else fc[sta][h[sta]]='\0'; for(i=m+1;i<=end;i++) { fc[h]='1'; h++; } if(m==sta&&(m+1)==end)//如果分组后首元素的下标与中间元素的相等, {//并且和最后元素的下标相差为1,则编码码字字符串结束 fc[m][h[m]]='\0'; fc[end][h[end]]='\0'; } else EnterQueue(Q,m+1,end); } for(i=1;i<=n;i++)/*打印编码信息*/ { printf("%c: ",FN.ch); printf("%s\n",fc); } system("pause"); } #include #include #include #include #defineN100 #defineM2*N-1 typedefchar*HuffmanCode[2*M]; typedefstruct { charweight; intparent; intLChild; intRChild; }HTNode,Huffman[M+1]; typedefstructNode { intweight;/*叶子结点的权值*/ charc;/*叶子结点*/ intnum;/*叶子结点的二进制码的长度*/ }WNode,WeightNode[N]; /***产生叶子结点的字符和权值***/ voidCreateWeight(charch[],int*s,WeightN
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 压缩 代码 非常 简单
![提示](https://static.bdocx.com/images/bang_tan.gif)