El concepto básico y la creación del árbol de Huffman (c / c ++)

1. Algunos conceptos básicos

1. Ruta : La rama de un nodo a otro en el árbol constituye la ruta entre estos dos nodos.
2. Longitud de la ruta : el número de ramas en la ruta se denomina longitud de la ruta.
3. La longitud de la ruta del árbol : la suma de la longitud de la ruta desde la raíz del árbol hasta cada nodo.
4. Derecha : Una cantidad asignada a una entidad es una descripción numérica de algunos o algunos atributos de la entidad.
5. La longitud de la ruta ponderada del nodo: el producto de la longitud de la ruta desde el nodo hasta la raíz del árbol y el peso en el nodo.
6. La longitud de la ruta ponderada del árbol: la suma de las longitudes de la ruta ponderada de todos los nodos de hojas del árbol, generalmente registrada como:
Inserte la descripción de la imagen aquí
7. Árbol de Huffman : suponga que hay m pesos {w1, w2, ..., wm} , Se puede construir un árbol binario con n nodos de hoja y el peso de cada nodo de hoja es wi El árbol binario con la longitud de ruta ponderada más pequeña WPL se denomina árbol binario óptimo o árbol de Huffman.
Nota:
(1) Un árbol binario completo no es necesariamente un árbol de Huffman;
(2) El nodo con un peso mayor está más cerca del nodo raíz;
(3) El árbol de Huffman no es único, pero la longitud de la ruta ponderada del árbol es cierto igual;

En segundo lugar, construya el árbol de Huffman

Estructura del nodo del árbol de Huffman:
Inserte la descripción de la imagen aquí
representación de almacenamiento del árbol de Huffman

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

Número de nodos del árbol de Huffman:
Inserte la descripción de la imagen aquí

Ejemplo: Dado que w = (5,29,7,8,14,23,3,11), genere un árbol de Huffman y calcule la longitud de la ruta ponderada del árbol. Y dar el estado inicial y el estado final de la estructura de almacenamiento HT durante su construcción.

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí
【Descripción del 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的权值为左右孩子权值之和
  }

Tres, codificación de Huffman

Marque la rama izquierda del árbol como 0 y la rama derecha como 1; (izquierda 0 y derecha 1)
Inserte la descripción de la imagen aquí

derecho Codificación de 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

Cuarto, la creación del árbol Huffman.

Requisitos:
1. Ingrese ny la probabilidad de n caracteres desde el teclado.
Por ejemplo: se sabe que solo n tipos de caracteres pueden aparecer en un determinado sistema de comunicación, y sus probabilidades son respectivamente 0.05, 0.29, 0.07, 0.08, 0.14, 0.23, 0.03, 0.11. Intente diseñar un código Huffman para crear un árbol de Huffman.
2. Utilice almacenamiento secuencial.

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

Supongo que te gusta

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