⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 haffmantree.h

📁 利用哈夫曼编码进行信息通信可以大大提高信道利用率
💻 H
字号:
struct HaffNode
//哈夫曼树的结点结构
{    
	char letter;
	int weight;								//权值
	int flag;								//标记
	int parent;								//双亲结点下标
	int leftChild;							//左孩子下标
	int rightChild;							//右孩子下标
};

struct Code
//存放哈夫曼编码的数据元素结构
{
	int bit[MaxBit];							//数组
	int start;								//编码的起始下标
	int weight;	                            //字符的权值
	char letter;
};

void Haffman(char a1[],int weight[], int n, HaffNode haffTree[])
//建立叶结点个数为n权值为weight的哈夫曼树haffTree
{
	int j, m1, m2, x1, x2;

	//哈夫曼树haffTree初始化。n个叶结点的哈夫曼树共有2n-1个结点
	for(int i = 0; i < 2 * n - 1 ; i++)
	{
		if(i < n) {haffTree[i].weight = weight[i];  haffTree[i].letter=a1[i];}
		else      haffTree[i].weight = 0;
		haffTree[i].parent = 0;
		haffTree[i].flag   = 0;
		haffTree[i].leftChild = -1;
		haffTree[i].rightChild = -1;
	}

	//构造哈夫曼树haffTree的n-1个非叶结点
	for(i = 0;i < n-1;i++)
	{
		m1 = m2 = MaxValue;
		x1 = x2 = 0;
		for(j = 0; j < n+i;j++)
		{
			if(haffTree[j].weight < m1 && haffTree[j].flag == 0)
			{
				m2 = m1;
				x2 = x1;
				m1 = haffTree[j].weight;
				x1 = j;
			}
			else if(haffTree[j].weight < m2 && haffTree[j].flag == 0)
			{
				m2 = haffTree[j].weight;
				x2 = j;
			}
		}

		//将找出的两棵权值最小的子树合并为一棵子树
		haffTree[x1].parent  = n+i;   
		haffTree[x2].parent  = n+i;
		haffTree[x1].flag    = 1;
		haffTree[x2].flag    = 1;
		haffTree[n+i].weight = haffTree[x1].weight+haffTree[x2].weight;
		haffTree[n+i].leftChild = x1;
		haffTree[n+i].rightChild = x2;
	}
}

void HaffmanCode(char a1[],HaffNode haffTree[], int n, Code haffCode[])
//由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode
{
	Code *cd = new Code;
	int child, parent;

	//求n个叶结点的哈夫曼编码
	for(int i = 0; i < n; i++)		
	{
		cd->start = n-1;					//不等长编码的最后一位为n-1
		cd->weight = haffTree[i].weight;     //取得编码对应权值的字符
		cd->letter = a1[i] ;
		child = i;
		parent = haffTree[child].parent;

		//由叶结点向上直到根结点
		while(parent != 0)
		{
			if(haffTree[parent].leftChild == child)
				cd->bit[cd->start] = 0;				//左孩子结点编码0
			else							
				cd->bit[cd->start] = 1;				//右孩子结点编码1
			cd->start--;
			child = parent;
			parent = haffTree[child].parent;
		}

		//保存叶结点的编码和不等长编码的起始位
		for(int j = cd->start+1; j < n; j++) 
			haffCode[i].bit[j] = cd->bit[j];
		haffCode[i].start  = cd->start;
		haffCode[i].weight = cd->weight;		//记住编码对应的权值 
		haffCode[i].letter = cd->letter;        //记住编码对应权值的字符
	}
}


void encoding( int codelist[],char a[],int s,Code haffCode[],int n,int &y)
  //  将输入的明文转化为哈夫曼编码,保存在codelist[]中
{
	for(int i=0;i<s;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(a[i]==haffCode[j].letter)
			{
				for(int k=haffCode[j].start+1;k<n;k++)
				{
					codelist[y]=haffCode[j].bit[k];
					y++;
				}
				break;
			}
		}
	}
	
    cout<<"发射端:"<<endl;
	cout<<"输入的明文为:";
	for(i=0;i<s;i++)
	{ cout<<a[i];}
	cout<<endl<<"经过编码后为:";
	for(i=0;i<y;i++)
	{cout<<codelist[i];}
	cout<<endl;
}
  

  void decoding( int codelist[],int y,HaffNode haffTree[],int n)
	  //将已编好的哈夫曼编码译成明文
  {
	  cout<<"接收端:"<<endl;
	  cout<<"接收到的哈夫曼编码为:";
	  for( int i=0;i<y;i++)
	  {cout<<codelist[i];}
	  cout<<endl<<"解码为:";

       int nd;
		  nd=2*n-2;
	  for(  i=0;i<y+1;i++)
	  {
		   if((haffTree[nd].leftChild==-1)&&(haffTree[nd].rightChild==-1))  //判断是否是叶结点,
		   {   cout<<haffTree[nd].letter;                                   //若是,则输出该结点的letter
		       nd= 2*n-2 ;
		   }
            if(codelist[i]==0)                //若是0,指向左孩子结点
		   {  nd=haffTree[nd].leftChild;}
		    else                              //若是1,指向右孩子结点
			   nd=haffTree[nd].rightChild;
		  
	  }
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -