O conceito básico e a criação da árvore de Huffman (c / c ++)

1. Alguns conceitos básicos

1. Caminho : a ramificação de um nó a outro na árvore constitui o caminho entre esses dois nós.
2. Comprimento do caminho : O número de ramificações no caminho é chamado de comprimento do caminho.
3. O comprimento do caminho da árvore : a soma do comprimento do caminho desde a raiz da árvore até cada nó.
4. Direito : Uma quantidade atribuída a uma entidade é uma descrição numérica de alguns ou alguns atributos da entidade.
5. O comprimento do caminho ponderado do nó: o produto do comprimento do caminho do nó à raiz da árvore e o peso no nó.
6. O comprimento do caminho ponderado da árvore: a soma dos comprimentos do caminho ponderado de todos os nós de folha na árvore, geralmente registrados como:
Insira a descrição da imagem aqui
7. Árvore de Huffman : Suponha que haja pesos m {w1, w2, ..., wm} , Uma árvore binária com n nós folha pode ser construída, e o peso de cada nó folha é wi. A árvore binária com o menor comprimento de caminho ponderado WPL é chamada de árvore binária ótima ou árvore de Huffman.
Nota:
(1) Uma árvore binária completa não é necessariamente uma árvore de Huffman;
(2) O nó com maior peso está mais próximo do nó raiz;
(3) A árvore de Huffman não é única, mas o comprimento do caminho ponderado da árvore é certo igual;

Em segundo lugar, construa a árvore Huffman

Estrutura do nó da árvore de Huffman:
Insira a descrição da imagem aqui
representação de armazenamento da árvore de Huffman

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

Número de nós da árvore Huffman:
Insira a descrição da imagem aqui

Exemplo: Dado que w = (5,29,7,8,14,23,3,11), gere uma árvore de Huffman e calcule o comprimento do caminho ponderado da árvore. E dar o estado inicial e o estado final da estrutura de armazenamento HT durante sua construção.

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

Insira a descrição da imagem aqui
【Descrição do algoritmo】

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的权值为左右孩子权值之和
  }

Três, codificação Huffman

Marque o ramo esquerdo da árvore como 0 e o ramo direito como 1; (esquerda 0 e direita 1)
Insira a descrição da imagem aqui

direito Codificação Huffman
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

Quarto, a criação da árvore Huffman

Requisitos:
1. Insira ne a probabilidade de n caracteres do teclado.
Por exemplo: Sabe-se que apenas n tipos de caracteres podem aparecer em um determinado sistema na comunicação, e suas probabilidades são, respectivamente, 0,05, 0,29, 0,07, 0,08, 0,14, 0,23, 0,03, 0,11. Tente projetar um código de Huffman para criar uma árvore Huffman.
2. Use o armazenamento sequencial.

#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;
}

Acho que você gosta

Origin blog.csdn.net/gets_s/article/details/106160072
Recomendado
Clasificación