Class notes: conversion of trees, forests and binary trees, Huffman trees

The conversion
tree of tree, forest and binary tree is converted into binary tree :
1. Brothers add line;
2. Keep the connection between parents and the first child, delete the connection with other children;
3. Turn clockwise to make it clear.
The preorder traversal of the tree is equivalent to the preorder traversal of the binary tree, and the postorder traversal of the tree is equivalent to the midorder traversal of the binary tree.
Converting the forest to a binary tree :
⑴ Convert each tree in the forest into a binary tree;
⑵ Start with the second binary tree, and then take the root node of the latter binary tree as the right child of the root node of the previous binary tree, when all binary trees After being connected, the binary tree obtained at this time is the binary tree obtained by forest conversion.
Convert a binary tree to a tree or a forest :
⑴ Add a line-if a node x is the left child of its parent y, then use the line with the right child of node x, the right child of right child, ... with node y Connect together;
⑵ Go to line — delete the connection between all the parent nodes and the right child node in the original binary tree;
⑶ Level adjustment — organize the trees or forests obtained by the two steps of ⑴ and ⑵ to make them distinct .
Forest traversal
There are two methods of forest traversal:
⑴ preorder (root) traversal: preorder traversal of the forest is the preorder traversal of each tree in the forest.
⑵Post-order (root) traversal: Post-order traversal of the forest is to traverse every tree in the post-order.
Optimal Binary Tree-Huffman Tree and Huffman Coding
Related Concepts
Weight of leaf nodes: A meaningful amount of value given to leaf nodes.
Weighted path length of the binary tree: Let the binary tree have n weighted leaf nodes, and the sum of the product of the path length from the root node to each leaf node and the weight of the corresponding leaf node.
Huffman tree: given a set of leaf nodes with certain weights, the binary tree with the smallest weighted path length.
The characteristics of the Huffman tree :
1. The leaf nodes with larger weights are closer to the root node, and the leaf nodes with smaller weights are farther from the root node.
2. There are only nodes with degree 0 (leaf node) and degree 2 (branch node), and there is no node with degree 1.
The basic idea of ​​the Huffman algorithm :
⑴ Initialization: construct n binary trees with only one root node from the given n weights {w1, w2, ..., wn}, thus obtaining a set of binary trees F = {T1, T2, …, Tn};
⑵ Selection and merging: Select two binary trees with the smallest weight of the root node in F as the left and right subtrees to construct a new binary tree, and the weight of the root node of this new binary tree It is the sum of the weights of the root nodes of the left and right subtrees;
⑶ Delete and join: delete the two binary trees as left and right subtrees in F, and add the newly created binary tree to F;
⑷ Repeat ⑵ ⑶Two steps, when there is only one binary tree left in set F, this binary tree is the Huffman tree.
Storage structure of the Huffman algorithm
Set an array huffTree [2n-1] to save the information of each point in the Huffman tree, and the node structure of the array elements.

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

Pseudocode
1. The array huffTree is initialized, and the parents and left and right children of all element nodes are set to -1;
2. The weight of the first n elements of the array huffTree is set to the given value w [n];
3. Perform n-1 Sub-merging
3.1. Select the two root nodes with the smallest weights in the binary tree set, whose subscripts are i1, i2;
3.2. Combine the binary trees i1, i2 into a new binary tree k (the initial value is n; in order; Increasing);

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

Application of Huffman tree - Huffman
coding : each object to a binary bit string flag represent a set of objects.
Example: ASCII, command system
isometric coding : the length of a binary bit string representing a group of objects is equal.
Unequal length coding : the length of the binary bit string representing a group of objects is not equal.
Prefix encoding : any encoding in a set of encodings is not a prefix of any other encoding.
The prefix encoding guarantees that there will not be many possibilities when decoding.
Clue Binary
Tree The traversal operation of the binary tree is the process of linearizing the nodes in the binary tree according to a certain rule.
When the binary linked list is used as the storage structure, only the left and right child information of the node can be found, but the predecessor and successor information of the node in the traversal sequence cannot be directly obtained.
To obtain this information, you can use the following two methods: The
first method is to traverse the binary tree once, you can get the precursor and successor of the node during the traversal, but this dynamic access wastes time; the
second method is to make full use of The empty chain domain in the binary linked list preserves the predecessor and successor information of the nodes in the traversal process.
There are 2n chain domains in the binary list with n nodes, but there are only n-1 useful non-empty chain domains, and the remaining n + 1 chain domains are empty. The remaining n + 1 empty chain domains can be used to store the predecessor and successor information of the nodes in the traversal process.
Clue linked list
clue : The pointer that points the empty pointer field in the binary fork list to the predecessor and successor nodes is called the clue;
clue : the process of making the empty link domain of the node in the binary fork list store its predecessor or successor information Clueing;
clue binary tree: Binary tree with clues is called clue binary tree.
The storage structure of the thread binary tree: the linked list of
nodes

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

There are 4 kinds of traversal methods of binary trees, so there are 4 kinds of predecessors and successors in the sense, there are 4 kinds of clue binary trees: ⑴ preorder clue binary tree; ⑵ midorder clue binary tree; ⑶ postorder clue binary tree; ⑷ sequence clue binary tree . Declaration of a sorted list of linked lists in a
binary tree

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

The establishment of a mid-order thread linked list-constructor
analysis: building a thread linked list is essentially to change the null pointer in the binary linked list to point to the predecessor or successor, and the information of the predecessor or successor can only be obtained when traversing the binary tree .
Create a binary list (with flags)-> traverse the binary tree, change the null pointer to the clue to
create a binary list with flags

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

Middle-order clue-based binary tree: The
basic idea of recursive realization : To complete clue-making during traversal, pre-order, middle-order, and post-order traversal can be used to establish pre-order clue binary tree, mid-order clue binary tree and post-order clue binary tree.
The construction method of the middle-order clue binary tree : the middle-order clues the left subtree of the root node; clues the root node; the middle-order clues the right subtree of the root node; the
function sets the formal parameter root and the global variable pre, Represent the root node and its precursor node of the tree to be processed

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

The traversal algorithm of the linked list of clues: the middle order traverses the middle order clue tree to
find the first node : first start from the root of the tree, and follow the left pointer to find the "most left" (it must be the first node of the middle order)
Node successor determination : if the right pointer of a node is a clue, the right pointer is the next node to be traversed, if the right pointer is not a clue, then its middle-order successor is the "leftmost" of its right subtree Node;
when the traversal stops : the right pointer of a node == NULL
finds the successor of the middle-order traversal of the node in the middle-order clue tree

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

The traversal algorithm of the thread linked list: middle-order traversal of the middle-order clue tree

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;
}
Published 48 original articles · Like 25 · Visit 2453

Guess you like

Origin blog.csdn.net/qq_43628959/article/details/103222306