首页 > 编程语言 >哈夫曼树及哈夫曼编码 C++代码实现

哈夫曼树及哈夫曼编码 C++代码实现

时间:2023-08-27 11:38:08浏览次数:41  
标签:编码 typedef 哈夫曼 HT start C++ HC 树及


 

/*哈夫曼编码*/

#include <iostream>
using namespace std;
 
//********************************
//构造哈夫曼树
//********************************
 
/*哈夫曼树顺序表的定义*/
typedef struct
{
       intweight;
       intparent,lchild,rchild;
}HTNode;
 
typedef HTNode * HuffmanTree;
 
 
/*初始化一个哈夫曼树*/
void InitHuffmanTree(HuffmanTree&HT,int m)
{
       inti;
       HT=newHTNode[m];
       for(i=0;i<m;i++)
       {
              HT[i].weight=0;
              HT[i].parent=-1;
              HT[i].lchild=-1;
              HT[i].rchild=-1;
       }
}
//****************************************
//从n个结点中选取最小的两个结点
//****************************************
void SelectMin(HuffmanTree &HT,intn,int &min1,int &min2)
{
       typedefstruct
       {
              intNewWeight;//存储权
              intp;//存储该结点所在的位置
       }TempNode,*TempTree;
 
       TempTreeTT=new TempNode[n];
 
       inti,j;
 
       j=0;
       for(i=0;i<n;i++)
       {
              if(HT[i].parent==-1&& HT[i].weight!=0)
              {
                     TT[j].NewWeight=HT[i].weight;
                     TT[j].p=i;
                     j++;
              }
       }//将HT中没有双亲的结点存储到TT中
 
       intm1,m2;
       m1=m2=0;
       for(i=0;i<j;i++)
       {
              if(TT[i].NewWeight<TT[m1].NewWeight)//此处不让取到相等,是因为结点中有相同权值的时候,m1取最前的
那个。
                     m1=i;
       }
       for(i=0;i<j;i++)
       {
              if(m1==m2)
                     m2++;//当m1在第一个位置的时候,m2向后移一位
              if(TT[i].NewWeight<=TT[m2].NewWeight&& i!=m1)//此处取到相等,是让在结点中有相同的权值的时候,
                                                                                                        
                                   //m2取最后的那个。
                     m2=i;
       }
 
       min1=TT[m1].p;
       min2=TT[m2].p;
 
}
 
/*创建哈夫曼树*/
void CreateHaffmanTree(HuffmanTree&HT,int n)
{
       inti;
       intm;
       intmin1,min2;
       if(n<=1)
              cout<<"ParameterError!";
       m=2*n-1;//哈夫曼树中结点的个数
      
       InitHuffmanTree(HT,m);
 
       for(i=0;i<n;i++)
       {
              cin>>HT[i].weight;
       }
 
       for(i=n;i<m;i++)
       {
              SelectMin(HT,i,min1,min2);
              HT[min1].parent=i;
              HT[min2].parent=i;
              HT[i].lchild=min1;
              HT[i].rchild=min2;
              HT[i].weight=HT[min1].weight+HT[min2].weight;
             
              cout<<min1<<""<<min2<<endl;
       }
}
 
//***********************************
//构造哈夫曼编码
//***********************************
 
/*哈夫曼编码的定义*/
typedef struct
{
       charch;
       charbits[10];
}CodeNode;
 
typedef CodeNode * HuffmanCode;
 
/*哈夫曼编码的构造*/
void CreateHuffmanCode(HuffmanTree&HT,HuffmanCode &HC,int n)
{
       inti;
       intstart;
       intc;
       intp;
       char*cd;
       charq;
       HC=newCodeNode[n];
       cd=newchar[n];
       cd[n-1]='/0';
 
       for(i=0;i<n;i++)
       {
              cin>>q;
              HC[i].ch=q;
              start=n-1;
             
              c=i;
              while((p=HT[c].parent)>=0)
              {
                     --start;
                     cd[start]=(HT[p].lchild==c)?'0':'1';
                     c=p;
              }
              strcpy(HC[i].bits,&cd[start]);
       }
      
       deletecd;
}
 
/*哈夫曼编码的输出*/
void OutputHuffmanCode(HuffmanCode&HC,int n)
{
       inti;
       for(i=0;i<n;i++)
       {
              cout<<HC[i].ch<<""<<HC[i].bits<<endl;
       }
}
 
void main()
{
       inti;
       cout<<"输入字符个数:";
       cin>>i;
       HuffmanTreeHT;
       HuffmanCodeHC;
 
       CreateHaffmanTree(HT,i);
       CreateHuffmanCode(HT,HC,i);
       OutputHuffmanCode(HC,i);
}

 

唉,这个程序,用了我两天的时间,主要在一个地方,就是SelectMin()函数,其他的都简单,就是这里是一个瓶颈,突破它,就出来了。我参考了很多人写的这个函数,但是我测试了几组数据,都不符合,虽然是一个很简单的事情,可是用程序写出来,就不那么容易了。我自己写的我觉得比较繁杂,不是很简练,也许是算法不好,希望有谁有好的算法的,请指点一下!

 

标签:编码,typedef,哈夫曼,HT,start,C++,HC,树及
From: https://blog.51cto.com/u_5173797/7251970

相关文章

  • 稀疏矩阵的压缩存储及转置,快速转置法,C++代码实现
    /*稀疏矩阵的压缩存储及转置*/#include<iostream>usingnamespacestd;/*三元组顺序表的类型定义*/#defineitemSize100typedefstruct{introw,col;intitem;}thNode;typedefstruct{thNode*data;//data[0]不用intm,n,t;//分别表示行数、列......
  • 选择排序——简单选择排序和堆排序,C++代码实现
    #include<iostream>usingnamespacestd;typedefstruct{ intr[100+1]; intlength;}SqList;//简单选择排序voidSimpleSlectSort(SqList&L){ intmin,i,j; for(i=1;i<L.length;i++) { min=i; for(j=i+1;j<=L.length;j++) if(L.r[j]<L.r[m......
  • 循环队列的定义、入队、出队等操作 C++代码实现
    #include<iostream>usingnamespacestd;/*循环队列的类型定义*/constintQueue_Size=100;typedefstructcirclQueue{char*elem;intrear;intfront;intqueueSize;}circlQueue;/*初始化*/voidinitQueue_C(circlQueue&......
  • 顺序栈的定义、初始化、出栈、入栈等操作 C++代码实现
     #include<iostream>usingnamespacestd;/*顺序栈的定义*/#defineStack_Size100typedefstructsqStack{char*elem;inttop;intstackSize;//栈数组长度}sqStack;/*顺序栈的初始化*/voidinitStack_Sq(sqStack&S){S.elem=ne......
  • 用线性表实现的通讯录管理 C++代码
    /****************************************//*主控菜单处理测试程序main2.c************//***************************************/#include<iostream>#include<string>usingnamespacestd;#defineLIST_INIT_SIZE100#defineLISTINCREMENT10intOK=......
  • 用单链表实现一元多项式相加 C++代码
     #include<iostream>usingnamespacestd;/*结点的定义*/typedefstructLNode{floatcoef;intexp;structLNode*next;}LNode;typedefLNode*Polynomial;/*多项式的初始化*/voidinitDuoX(Polynomial&Px){Px=newLNode;......
  • 双链表的定义、初始化、插入、删除,C++代码实现的算法
    #include<iostream>usingnamespacestd;/*双向链表类型定义*/typedefstructduNode{chardata;structduNode*prior;structduNode*next;}duNode;typedefduNode*duLinklist;//指针类型,故访问它的成员用“->”。/*初始化双向链表*/voidinitLinkl......
  • 链队列的实现,C++代码实现
    /*链队列的实现*/#include<iostream>usingnamespacestd;/*链队列类型定义*/typedefstructQNode{structQNode*next;chardata;}QNode,*queuePtr;//结点的定义typedefstructlinkQueue{queuePtrrear;queuePtrfront;}linkQueue;//队列的定......
  • 基于QT和C++实现的停车场管理系统
    基于QT和C++实现的停车场管理系统停车场管理系统简介一、 问题描述设停车场是一个可停放若干辆辆汽车的狭多层平面区域,且只有一个大门可供汽车进出。若车场内已停满汽车,则后来的汽车只能在门外的狭长便道上等候,一旦停车场内有车开走,则排在便道上的第一辆车即可进入。每辆停放在......
  • 力扣-2. 两数相加(C++题解)
    题目链接:https://leetcode.cn/problems/add-two-numbers/description/给你两个 非空的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字0之......