Trees and their traversal

Tree

tree definition

What is stored in such a hierarchical relationship is a tree, which is a non-linear structure.
Insert image description here
Define recursively.

Professional definition:

  • There is exactly one node called the root.
  • There are several disjoint subtrees, which are themselves trees.

Popular definition:

  • Trees are composed of nodes and edges.
  • Each node node has only one parent node but can have multiple child nodes.
  • There is one exception, this node has no parent node, this node is called the root node.

Terminology

  • Node: It is a circle.
  • Parent node: the node immediately preceding the current node.
  • Child node: the child node connected to the parent node.
  • Descendants: All nodes under the parent node.
  • Depth: The number of layers from the root node to the lowest layer is called depth.
  • Leaf node: A node that has no child nodes.
  • Non-terminal node: It is actually a non-leaf node, a node with child nodes.
  • Root node: Check if there are any child nodes.
  • Degree: The number of child nodes is called degree.

tree classification

  • General tree: The number of child nodes of any node is not limited
  • Binary tree: Any node has a maximum of two child nodes, and the position of the child nodes cannot be changed.
  • Forest: There are disjoint trees. When the ordinary trees are put together, they are a forest.

Binary tree

Classification

  • General binary tree
  • Full binary tree: A binary tree in which one more node cannot be added without increasing the number of layers of the tree is a full binary tree.
  • Complete binary tree: If only the rightmost consecutive nodes at the bottom of the full binary tree are deleted, the resulting binary tree is a complete binary tree.
    A full binary tree is a special case of a complete binary tree.

storage

Continuous storage (complete binary tree)

If you want to store a general binary tree in an array, you must first convert the general binary tree into a complete binary tree.

eg:
Insert image description here
First of all, this is not a complete binary tree, because a complete binary tree is first a full binary tree, and then it is chopped at the bottom level. Therefore, to use continuous storage, you must first turn this binary tree into a complete binary tree.

Insert image description here
First, it becomes a full binary tree, and then the rightmost part of the bottom layer is deleted, and it becomes a complete binary tree.
Insert image description here
The yellow wireframe does not need to be saved. (First convert it into a full binary tree, and then delete the rightmost point of the last layer to form a complete binary tree.) The red ones are valid nodes. Others cannot restore the original appearance of the binary tree through scattered red valid nodes. (Sorting is done by centering first.)
Trees are non-linear, and the result of converting non-linear numbers into linear structures is unknown.
The array can only be stored in the form of a complete binary tree, that is, it cannot store only valid nodes, because its original appearance cannot be restored after sorting first. So save all the points in order to restore them.

Advantages: Finding the parent node and child nodes of a node is fast.
Disadvantages: consumes too much memory space.

chain storage

Create a continuous storage through the pointer field.

General tree storage

  1. Parent notation: It is very convenient to find the parent node because it is followed by a subscript.
  2. Child representation: It is convenient to find child nodes, followed by child nodes.
  3. Parent-child representation: There are linked lists, arrays, subscripts, and pointer fields. It is very convenient to find parent nodes and child nodes, but the code is complicated.
  4. Binary tree representation: Convert an ordinary tree into a binary tree for storage. The specific conversion method is to try to ensure that the left pointer field of any node points to its first child and the right pointer field points to its next sibling node, as long as this is satisfied. Conditions can convert an ordinary number into a binary tree. (When converting, there are only children on the left, and the brothers on the right are parallel to the child. That is, if an ordinary number is converted into a binary tree, there will be no right subtree. For example, 2, 3, 4, and 5 below, only 2 is the real child. Then 3, 4, and 5 are all items that are parallel to them, arranged on the right. 3 also has no left sibling, so 4 is arranged on the right, and the same is true for 5.) Eg is as follows, convert
    an ordinary tree into a binary tree.
    Insert image description here

forest storage

Several trees that do not intersect form a forest.
Insert image description here
First convert the forest into a binary tree and then store it. The binary tree storage rule of the forest is: treat B as the brother of A, and treat G as the brother of B.
Insert image description here
The steps for converting a forest into a binary tree are the same as before converting a general tree into a binary tree.

clue binary tree

When a binary linked list is used as the storage structure of a binary tree, it is easy to find the left and right children of a node; but in general, it is not possible to directly find the predecessor and successor nodes of the node in a certain traversal sequence.
Insert image description here
Because there are n+1 pointer fields left, they are used to store the addresses of the previous and subsequent pointers, which are called clues.
Insert image description here
Insert image description here
You can use ltag and rtag to distinguish whether it is a child or a clue. (Left child and predecessor, right child and successor)

//线索二叉树的结点结构
typedef struct BiThrNode{
    
    
	int data;
	int ltag, rtag;
	struct BiThrNode *lchild, rchild;
}BiThrNode, *BiThrTree;

Insert image description here
Insert image description here
Because there are still two pointer fields dangling at the beginning and end, a head node can be added to point to the head node.
Insert image description here

Huffman tree

Insert image description here
It is equivalent to rearranging a weighted tree into a binary tree that takes into account the optimal weight.

Construction steps

Insert image description here
Insert image description here
Two objects with the same weight are directly connected. Those with different weights are arranged according to the principle that the smaller weight is the left child and the larger weight is the right child.

Traverse

Convert non-linear trees into non-linear sequences.

preorder traversal

The root node is visited first, then the left subtree is visited sequentially, and then the right subtree is visited sequentially. Suppose the binary tree is as follows:
Insert image description here

Using the idea of ​​recursion, first visit the root node A, then visit the left subtree in order, and then visit the right subtree in order. When accessing the left subtree, because the left subtree is also a tree, it will go around to visit the root node B first, and then look at the left subtree and right subtree along the way, that is, the left subtree of B is D. B has no right subtree, because D has no left subtree and right subtree and is empty, then the recursion ends and BD access is completed; then the right subtree of A is traversed in order, and the right subtree is a binary tree, and then the root is Starting at the node, traverse the left subtree, and then traverse the right subtree. The visit is complete only after all visits are completed.
eg:
Insert image description here
The last traversed node is ABCDEFLQMNS.

inorder traversal

The left subtree is traversed in inorder, then the root node is visited, and the right subtree is traversed in inorder.
Insert image description here
The left subtree is traversed in mid-order first. The left subtree of B is empty, so the root node of the left subtree is visited first, which is B. Therefore, B is visited first. After B visits the right subtree of B, it is also non-empty, so In recursive thinking, the right subtree of B first traverses the left subtree in in-order, and the left subtree of B is the left subtree of C, so D is visited first, then the root node C, and then E.
The final order is BDCEALFNQM

eg:
Insert image description here

Traversal order: BDCAMQELN

Subsequent traversal

The left subtree is traversed in inorder, the right subtree is traversed in inorder, and then the root node is visited. Traversal is judged in the order of root nodes.
e.g.:
Insert image description here

Traversal order: BDMFLECA (first all left, then all right, and finally root)

Insert image description here

Traversal order: NWTSFPLQM

Chain binary tree traversal specific code

# include <stdio.h>
# include <malloc.h>

struct BTNode
{
    
    
	char data;
	struct BTNode * pLchild; 
	struct BTNode * pRchild;
};

void PostTraverseBTree(struct BTNode * pT);
struct BTNode * CreateBTree(void);
void PreTraverseBTree(struct BTNode * pT);
void InTraverseBTree(struct BTNode * pT);

int main(void)
{
    
    
	struct BTNode * pT = CreateBTree();
	
//	PreTraverseBTree(pT);
//	InTraverseBTree(pT);
	PostTraverseBTree(pT);
	
	return 0;
}

void PostTraverseBTree(struct BTNode * pT)
{
    
    
	if (NULL != pT)
	{
    
    
		if (NULL != pT->pLchild)
		{
    
    
			PostTraverseBTree(pT->pLchild);
		}	
		if (NULL != pT->pRchild)
		{
    
    
				PostTraverseBTree(pT->pRchild);
		}
		printf("%c\n", pT->data);
	}
}

void InTraverseBTree(struct BTNode * pT)
{
    
    
	if (NULL != pT)
	{
    
    
		if (NULL != pT->pLchild)
		{
    
    
			InTraverseBTree(pT->pLchild);
		}
		
		printf("%c\n", pT->data);
	
		if (NULL != pT->pRchild)
		{
    
    
				InTraverseBTree(pT->pRchild);
		}	
	}
}

void PreTraverseBTree(struct BTNode * pT)
{
    
    
	if (NULL != pT)
	{
    
    
		printf("%c\n", pT->data);
	
		if (NULL != pT->pLchild)
		{
    
    
			PreTraverseBTree(pT->pLchild);
		}
		
		if (NULL != pT->pRchild)
		{
    
    
				PreTraverseBTree(pT->pRchild);
		}	
	}	
}

struct BTNode * CreateBTree(void)
{
    
    
	struct BTNode * pA = (struct BTNode *)malloc(sizeof(struct BTNode));
	struct BTNode * pB = (struct BTNode *)malloc(sizeof(struct BTNode));
	struct BTNode * pC = (struct BTNode *)malloc(sizeof(struct BTNode));
	struct BTNode * pD = (struct BTNode *)malloc(sizeof(struct BTNode));
	struct BTNode * pE = (struct BTNode *)malloc(sizeof(struct BTNode));

	pA->data = 'A';
	pB->data = 'B';
	pC->data = 'C';
	pD->data = 'D';
	pE->data = 'E';

	pA->pLchild = pB;
	pA->pRchild = pC;
	pB->pLchild = pB->pRchild = NULL;
	pC->pLchild = pD;
	pC->pRchild = NULL;
	pD->pLchild = NULL;
	pD->pRchild = pE;
	pE->pLchild = pE->pRchild = NULL;

	return pA;
}

Two traversal sequences are known to find the original binary tree

Simply knowing any of the three sequences, first and last, cannot restore the original binary tree sequence. When two sequences are known, the original binary tree can be deduced.

Given the preorder and inorder, find the postorder

Example 1:
Pre-order: ABCDEFGH
In-order: BDCEAFHG
Post-order: Because according to the pre-order, the first accessed must be the root node, so the root node is A, then in the in-order, the A in the middle is definitely the root node, next to A is the left subtree, and the one to the right of A is the right subtree. The left subtree BDCE and the right subtree FHG are determined. Now find the root nodes of the left and right subtrees respectively. According to the preorder sequence, the one that appears first must be the root. After that, the root node is determined to be BF, and then the next root node is determined to be C. Because the in-order traverses the left subtree first, D is the left subtree of C, and E is the right subtree of C. At this point, all the left subtrees of A are Finished pushing. The right subtree is similar. After pushing F, it is found that there are no points on the left side of F in the inorder sequence, which means that F has no left subtree, only the right subtree G, and there is H on the left side of G, so H is the left subtree of G.
So the post-order sequence is DECBHGFA
Insert image description here
Example 2:
Pre-order: ABDGHCEFI
In-order: GDHBAECIF
Find the post-order: the root node is A, the left subtree of A is GDHB, the right subtree is ECIF, among the left subtrees, the first root node is B, the left subtree of B is GDH, and D is the root node, so GH has two trees, G is the left subtree, and H is the right subtree. At this point, the left subtree of A is completely derived; the right subtree of A is ECIF. In ECIF, C is the root node, the left subtree of C is E, the right subtree of C is F, and the left subtree of F is I. At this point, the right subtree of A is completely derived.
Insert image description here
The suffix is: GHDBIEFCA

Find the preorder if the inorder and postorder are known

In-order: BDCEAFHG
Post-order: DECBHGFA
Looking for pre-order: the root node is A, and the last post-order node is the root node. So BDCE is the left subtree and FHG is the right subtree. F is the root node, and B is also the root node, because it appears last in each combination (according to the post-order) and is searched in the mid-order. B has no left subtree, only the right subtree DCE. C appears last in the post-order and is the root. (Which one appears last in the post-order is the root), so C has a left subtree and a right subtree. The left subtree is D and the right subtree is E. At this point, all the left subtrees of A have been pushed out; The right subtree of A is FHG, F is the root node, F only has the right subtree HG, the root node is G, and G has the left subtree H. At this point, the right subtree of A has been pushed out.
Insert image description here
Preface: ABCDEFGH

Given the preorder and postorder, find the middle order

Similar to the above two situations.

Tree Applications

  • Tree is an important form of data organization in database
  • The relationship between child and parent processes in the OS is also a tree.
  • Inheritance relationship of classes in object-oriented languages
  • Huffman tree
  • B-tree
  • B+tree
  • B* tree
  • red black tree
  • AVL tree

Guess you like

Origin blog.csdn.net/weixin_44673253/article/details/125749610