The basic concept and creation of Huffman tree (c/c++)

1. Some basic concepts

1. Path : The branch from one node to another in the tree constitutes the path between these two nodes.
2. Path length : The number of branches on the path is called the path length.
3. The path length of the tree : the sum of the path length from the root of the tree to each node.
4. Right : A quantity assigned to an entity is a numerical description of some or some attributes of the entity.
5. The weighted path length of a node: the product of the length of the path from the node to the root of the tree and the weight on the node.
6. The weighted path length of the tree: the sum of the weighted path lengths of all leaf nodes in the tree, usually recorded as:
Insert picture description here
7. Huffman tree : Suppose there are m weights {w1,w2,...,wm}, A binary tree with n leaf nodes can be constructed, and the weight of each leaf node is wi. The binary tree with the smallest weighted path length WPL is called the optimal binary tree or Huffman tree.
Note:
(1) A complete binary tree is not necessarily a Huffman tree;
(2) The node with a larger weight is closer to the root node;
(3) The Huffman tree is not unique, but the weighted path length of the tree is certain equal;

Second, construct the Huffman tree

Huffman tree node structure:
Insert picture description here
storage representation of Huffman tree

typedef struct{
    
    
 int weight;  //结点的权值
 int parent,lchild,rchild;  //结点的双亲、左孩子、右孩子的下标
}HTNode,*HuffmanTree;  //动态分配数组存储哈夫曼树

Number of Huffman tree nodes:
Insert picture description here

Example: Given that w=(5,29,7,8,14,23,3,11), generate a Huffman tree and calculate the weighted path length of the tree. And give the initial state and final state of the storage structure HT during its construction.

Insert picture description here
Insert picture description here

Insert picture description here
【Algorithm Description】

void CreateHT(HuffmanTree &HT,int n)
{
    
    
  if(n<=1)return ;
  m=2*n-1;
  HT=new HTNode[m+1];
  for(i=1;i<=m;++i)    //将1-m号单元的父结点、左孩子、右孩子的下标都初始化为0
   {
    
    
     HT[i].parent=0;
     HT[i}.lchild=0;
     HT[i}.rchild=0;
   }
  for(i=1;i<=n;++i)  //输入前n个结点的权值
   {
    
    
      cin>>HT[i].weight;
   }
  for(i=n+1;i<=m;++i)
  {
    
     //通过n-1次的选择、删除、合并来创建哈夫曼树
    Select(HT,i-1,s1,s2);
    //在HT[k](1<=k<=i-1)中选择两个其双亲域为0且权最小的结点,并返回他们在HT中的序号s1和s2
    HT[s1}.parent=i;
    HT[s2}.parent=i;
    //得到新结点i,从森林中删除s1,s2,将s1和s2的双亲域由0改为1
    HT[i].lchild=s1;   //s1作为i的左结点
    HT[i}.rchild=s2;  //s2作为i的右结点
    HT[i].weight=HT[s1].weight+HT[s2].weight;  //i的权值为左右孩子权值之和
  }

Three, Huffman coding

Mark the left branch of the tree as 0 and the right branch as 1; (left 0 and right 1)
Insert picture description here

right Huffman coding
5 0 0 0 0
3 0 0 0 1
11 0 0 1
23 0 1
29 1 0
14 1 1 1
7 1 1 0 0
8 1 1 0 1

Fourth, the creation of the Huffman tree

Requirements:
1. Input n and the probability of n characters from the keyboard.
For example: It is known that only n kinds of characters may appear in a certain system in communication, and their probabilities are respectively 0.05, 0.29, 0.07, 0.08, 0.14, 0.23, 0.03, 0.11. Try to design a Huffman code to create a Huffman tree.
2. Use sequential storage.

#include<iostream>
using namespace std;
//哈夫曼树的存储结构
typedef struct {
    
    
	int weight;  //结点的权重
	int parent, lchild, rchild;  //结点的双亲、左孩子、右孩子的下标
}HTNode,*HuffmanTree;
//封装两个最小结点
typedef struct {
    
    
	int s1;
	int s2;
}MIN;
//选择双亲为0且结点权值最小的两个结点
MIN Select(HuffmanTree HT, int n)
{
    
    
	int min, secmin,s1,s2;
	min = 10000;
	secmin = 10000;
	MIN code;
	s1 = 1; s2 = 1;
	for (int i = 1; i <= n; i++)
	{
    
    
		if (HT[i].parent == 0 && (HT[i].weight<min))
		{
    
    
			min = HT[i].weight;
			s1 = i;
		}
	}
	for (int i = 1; i <= n; i++)
	{
    
    
		if (HT[i].parent == 0 && (HT[i].weight<secmin) && (i != s1))
		{
    
    
			secmin = HT[i].weight;
			s2 = i;
		}
	}
	code.s1 = s1;
	code.s2 = s2;
	return code;

}
//创造哈夫曼树
void CreateHuffmanTree(HuffmanTree &HT, int num)
{
    
    
	
	int m;
	m = 2 * num - 1;
	HT = new HTNode[m + 1];
	for (int i = 1; i <= m; i++)
	{
    
    
		HT[i].parent = 0;
		HT[i].lchild = 0;
		HT[i].rchild = 0;
	}
	cout << "请输入每个叶子结点的权值:" << endl;
	for (int i = 1; i <= num; i++)
	{
    
    
		cin >> HT[i].weight;
	}
	
	for (int i = num + 1; i <= m; i++)
	{
    
    
		MIN min;
		min=Select(HT,i-1);
		HT[min.s1].parent = i;
		HT[min.s2].parent = i;
		HT[i].lchild = min.s1;
		HT[i].rchild = min.s2;
		HT[i].weight = HT[min.s1].weight + HT[min.s2].weight;
	}
	//输出哈夫曼树存储结构的末态
	for (int i = 1; i <= m; i++)
	{
    
    
		cout << "结点序号 " << i << " 权重 " << HT[i].weight << " parent " << HT[i].parent << " lchild " << HT[i].lchild << " rchild " << HT[i].rchild << endl;
	}

}

int main()
{
    
    
	cout << "开始创建哈夫曼树" << endl;
	int num;  //结点的个数
	cout << "请输入哈夫曼树叶子结点的个数:";
	cin >> num;
	//创造哈夫曼树
	HuffmanTree HT;
	CreateHuffmanTree(HT, num);
	return 0;
}

Guess you like

Origin blog.csdn.net/gets_s/article/details/106160072