Apuntes de clase: conversión de árboles, bosques y árboles binarios, árboles Huffman

El
árbol de conversión de árbol, bosque y árbol binario se convierte en árbol binario :
1. Hermanos agregan línea;
2. Mantenga la conexión entre los padres y el primer hijo, elimine la conexión con otros hijos;
3. Gire en el sentido de las agujas del reloj para que quede claro.
La travesía previa al pedido del árbol es equivalente a la travesía previa al pedido del árbol binario, y la travesía postorder del árbol es equivalente a la travesía midorder del árbol binario.
Convertir el bosque en un árbol binario :
⑴ Convierta cada árbol del bosque en un árbol binario;
⑵ Comience con el segundo árbol binario, y luego tome el nodo raíz del último árbol binario como hijo derecho del nodo raíz del árbol binario anterior, cuando todos los árboles binarios Después de estar conectado, el árbol binario obtenido en este momento es el árbol binario obtenido por conversión de bosque.
Convierta un árbol binario en un árbol o un bosque :
⑴ Agregue una línea, si un nodo x es el hijo izquierdo de su padre y, luego use la línea con el hijo derecho del nodo x, el hijo derecho del hijo derecho, ... con el nodo y Conéctese juntos;
⑵ Ir a línea: elimine la conexión entre todos los nodos principales y el nodo secundario derecho en el árbol binario original;
⑶ Ajuste de nivel: organice los árboles o bosques obtenidos por los dos pasos de ⑴ y ⑵ para hacerlos distintos .
Atravesando el bosque
travesía bosque dos métodos:
⑴ preámbulo (raíz) de recorrido: es decir, el preámbulo de un orden previo recorrido a través de cada bosque de árboles forestales.
⑵ Recorrido de orden posterior (raíz): el recorrido posterior del orden del bosque es atravesar cada árbol en el orden posterior. Conceptos relacionados con la
codificación óptima del árbol binario-árbol de Huffman y la codificación de Huffman Peso de los nodos de hoja: una cantidad significativa de valor dado a los nodos de hoja. Longitud de ruta ponderada del árbol binario: deje que el árbol binario tenga n nodos de hoja ponderados y la suma del producto de la longitud de ruta desde el nodo raíz hasta cada nodo de hoja y el peso del nodo de hoja correspondiente.



Árbol de Huffman: dado un conjunto de nodos de hoja con ciertos pesos, el árbol binario con la longitud de ruta ponderada más pequeña.
Las características del árbol Huffman :
1. Los nodos de hoja con pesos más grandes están más cerca del nodo raíz, y los nodos de hoja con pesos más pequeños están más lejos del nodo de raíz.
2. Solo hay nodos con grado 0 (nodo de hoja) y grado 2 (nodo de rama), y no hay nodo con grado 1.
La idea básica del algoritmo de Huffman :
⑴ Inicialización: construya n árboles binarios con un solo nodo raíz a partir de los n pesos dados {w1, w2, ..., wn}, obteniendo así un conjunto de árboles binarios F = {T1, T2, …, Tn};
⑵ Selección y fusión: seleccione dos árboles binarios con el menor peso del nodo raíz en F como los subárboles izquierdo y derecho para construir un nuevo árbol binario, y el peso del nodo raíz de este nuevo árbol binario Es la suma de los pesos de los nodos raíz de los subárboles izquierdo y derecho;
⑶ Eliminar y unir: elimine los dos árboles binarios como subárboles izquierdo y derecho en F, y agregue el árbol binario recién creado a F;
⑷ Repita ⑵ ⑶Dos pasos, cuando solo queda un árbol binario en el conjunto F, este árbol binario es el árbol Huffman.
Estructura de almacenamiento del algoritmo Huffman
Establezca una matriz huffTree [2n-1] para guardar la información de cada punto en el árbol Huffman y la estructura de nodos de los elementos de la matriz.

struct element 
{     
	int weight;       
	int lchild, rchild, parent; 
};

Pseudocódigo
1, huffTree matriz de inicialización, todos los elementos del nodo padre, izquierda y niños derecho se fijan en 1;
2, los primeros n elementos de la matriz de la derecha huffTree ajustar el valor de consigna W [n];
. 3, para n-1 Sub-fusión
3.1. Seleccione los dos nodos raíz con los pesos más pequeños en el conjunto de árboles binarios, cuyos subíndices son i1, i2;
3.2. Combine los árboles binarios i1, i2 en un nuevo árbol binario k (el valor inicial es n; en orden; Creciente);

void HuffmanTree(element huffTree[ ], int w[ ], int n ) {     
	for (i=0; i<2*n-1; i++) {        
		huffTree [i].parent= -1;        
		huffTree [i].lchild= -1;        
		huffTree [i].rchild= -1;        
	}     
	for (i=0; i<n; i++)         
		huffTree [i].weight=w[i];
	for (k=n; k<2*n-1; k++) {         
		Select(huffTree, &i1, &i2); 
		huffTree[k].weight=huffTree[i1].weight+huffTree[i2].weight;         
		huffTree[i1].parent=k;              
		huffTree[i2].parent=k;          
		huffTree[k].lchild=i1;      
		huffTree[k].rchild=i2;     
	} 
}

Aplicación de árbol de Huffman - Huffman
de codificación : cada objeto a un indicador binario cadena de bits representan un conjunto de objetos.
Ejemplo: ASCII,
codificación isométrica del sistema de comando : la longitud de una cadena de bits binaria que representa un grupo de objetos es igual.
Codificación de longitud desigual : la longitud de la cadena de bits binarios que representa un grupo de objetos no es igual.
Codificación de prefijo : cualquier codificación en un conjunto de codificaciones no es un prefijo de ninguna otra codificación.
La codificación del prefijo garantiza que no habrá muchas posibilidades al decodificar. Árbol
binario de pista
La operación transversal del árbol binario es el proceso de linealización de los nodos en el árbol binario de acuerdo con una determinada regla.
Cuando la lista enlazada binaria se usa como estructura de almacenamiento, solo se puede encontrar la información secundaria izquierda y derecha del nodo, pero la información predecesora y sucesora del nodo en la secuencia transversal no se puede obtener directamente.
Para obtener esta información, puede usar los siguientes dos métodos: el
primer método es atravesar el árbol binario una vez, puede obtener el precursor y el sucesor del nodo durante el recorrido, pero este acceso dinámico pierde tiempo; el
segundo método es hacer un uso completo de El dominio de la cadena vacía en la lista enlazada binaria conserva la información predecesora y sucesora de los nodos en el proceso transversal.
Hay 2n dominios de cadena en la lista binaria con n nodos, pero solo hay n-1 dominios de cadena útiles no vacíos, y los restantes dominios de cadena n + 1 están vacíos. Los restantes dominios de cadena vacía n + 1 se pueden usar para almacenar la información predecesora y sucesora de los nodos en el proceso transversal.
Pista
pista lista vinculada : el puntero que señala el campo de puntero vacío en la lista de bifurcación binaria al nodo predecesor y sucesor se llama pista;
pista : el proceso de hacer que el dominio de enlace vacío del nodo en la lista bifurcación binaria almacene su predecesor o sucesor Pista;
pista árbol binario: El árbol binario con pistas se llama árbol binario pista.
La estructura de almacenamiento del árbol binario de subprocesos: la lista vinculada de
nodos

enum flag {Child, Thread};  
template<class T> 
struct ThrNode 
{      
	T data;      
	ThrNode<T>  *lchild, *rchild;      
	flag ltag, rtag; 
};

Hay 4 tipos de métodos transversales de árboles binarios, por lo que hay 4 tipos de predecesores y sucesores en el sentido, hay 4 tipos de árboles binarios de pista: ⑴ árbol binario de pista previa;; árbol binario de pista midorder; ⑶ árbol binario de pista postorder; . Declaración de una lista ordenada de listas vinculadas en un
árbol binario

template<class T> 
class InThrBiTree{        
public:         
	InThrBiTree();               
	~ InThrBiTree( );             
	ThrNode *Next(ThrNode<T> *p);          
	void InOrder(ThrNode<T> *root); 
private:         
	ThrNode<T> *root;           
	ThrNode<T> *  Creat();          
	void ThrBiTree(ThrNode<T> *root); 
};

El establecimiento de un
análisis de constructor de lista enlazada de hilo de orden medio : construir una lista enlazada de hilo es esencialmente cambiar el puntero nulo en la lista enlazada binaria para apuntar al predecesor o sucesor, y la información del predecesor o sucesor solo puede obtenerse al atravesar el árbol binario .
Cree una lista binaria (con banderas) -> atraviese el árbol binario, cambie el puntero nulo a la pista para
crear una lista binaria con banderas

template<class T>
ThrNode<T>* InThrBiTree<T>::Creat( ){     
	ThrNode<T> *root;     
	T ch;     
	cout<<"请输入创建一棵二叉树的结点数据"<<endl;     
	cin>>ch;     
	if (ch=="#") 
		root = NULL;
	else{           
		root=new ThrNode<T>;              
		root->data = ch;          
		root->ltag = Child; 
		root->rtag = Child;          
		root->lchild = Creat( );          
		root->rchild = Creat( );      
	}   
	return root; 
}

Árbol binario basado en pistas de orden medio:
la idea básica de la realización recursiva : para completar la creación de pistas durante el recorrido transversal, de preorden, de orden medio y de orden posterior se puede utilizar para establecer un árbol binario de pista de orden previo, un árbol binario de pista de orden medio y un árbol binario de pista de orden posterior.
El método de construcción del árbol binario de pistas de orden medio: las pistas de orden medio del subárbol izquierdo del nodo raíz; pistas del nodo raíz; las pistas de orden medio el subárbol derecho del nodo raíz; la
función establece la raíz del parámetro formal y la variable global pre, Representar el nodo raíz y su nodo precursor del árbol a procesar

template<class T>  
void ThrBiTree<T>::ThrBiTree (ThrNode<T>*root) {       
	if (root==NULL) 
		return;
	ThrBiTree(root->lchild);   
	if (!root->lchild){
		root->ltag = Thread;            
		root->lchild = pre;
	}
	if (!root->rchild)
		root->rtag = Thread;
	if(pre != NULL){        
		if (pre->rtag==Thread)  
			pre->rchild = root;    
	}
	pre = root;
	ThrBiTree(root->rchild);
}

El algoritmo transversal de la lista vinculada de pistas: el orden medio atraviesa el árbol de pistas de orden medio para
encontrar el primer nodo : primero comience desde la raíz del árbol y siga el puntero izquierdo para encontrar el "más a la izquierda" (debe ser el primer nodo del orden medio)
Determinación del sucesor de nodo : si el puntero derecho de un nodo es una pista, el puntero derecho es el siguiente nodo que se va a atravesar, si el puntero derecho no es una pista, entonces su sucesor de orden medio es el "extremo izquierdo" de su subárbol derecho Nodo;
cuando se detiene el recorrido : el puntero derecho de un nodo == NULL
encuentra el sucesor del recorrido de orden medio del nodo en el árbol de pistas de orden medio

template<class T>
ThrNode<T>* InThrBiTree<T>::Next(ThrNode<T>* p) {     
	ThrNode<T>* q;
	if (p->rtag==Thread)
		q = p->rchild;
	else{            
		q = p->rchild;          
		while (q->ltag==Child) {             
			q = q->lchild;         
		}     
	}     
	return q; 
}

El algoritmo transversal de la lista enlazada de subprocesos: transversal de orden medio del árbol de pistas de orden medio

template<class T>  
void InThrBiTree<T>::InOrder(ThrNode<T> *root){     
	ThrNode<T>* p = root;     
	if (root==NULL)  
		return;
	while (p->ltag==Child){       
		p = p->lchild;    
	}     
	cout<<p->data<<" ";     
	while (p->rchild!=NULL){         
		p = Next(p);         
		cout<<p->data<<" ";
	}
	cout<<endl;
}
48 artículos originales publicados · Me gusta 25 · Visita 2453

Supongo que te gusta

Origin blog.csdn.net/qq_43628959/article/details/103222306
Recomendado
Clasificación