definition and basic terminology of trees
A tree is a finite set of n (n>=0) nodes t,t is empty when it is called an empty tree, otherwise it satisfies the following two conditions:
(1) There is only one specific node called root (Root);
(2) The remaining nodes can be divided into m (m>=0) non-intersecting subsets t1,t2,t3 ... Tm, where each subset is a tree and is called a subtree (subtree).
examples of tree-shaped structure applications :
1. Daily life: Family spectrum, administrative organization structure; catalogue of books
2, Computer: Resource Manager folder;
Compiler: Use the tree to represent the syntax structure of the source program;
Database system: Organize information with tree;
Analysis algorithm: Use the tree to describe its execution process;
3. Expression representation (e.g. A * b + (c–d/e) * f)
Professional terminology
1. Node degree (degree): the number of branches of a node's subtree
Leaf (leaf) (terminal node), branch node (non-terminal node), internal node (B, C, D, E, H), Degree of tree (3)
2. Children at the Junction (child)
Parent (parent) (d is the parent of H, I, J)
Brother (Sibling) (H, I, J each brothers)
Ancestors, descendants (descendants of B are E, K, L, F)
3. Hierarchy of nodes
The root node is the first layer. A node is on layer I, and its child is at Layer i+1. The depth of the tree (depth) is the number of cousins from the beginning to the next: parents on the same level of the knot, each other as cousins.
4. Ordered tree and unordered tree
Ordered Tree: Unordered tree:
5. Forest (forest) is a collection of M (m≥0) disjoint trees.
Structural characteristics of contrasting tree structure and linear structure
Linear structure: The first element has no precursor, the last element has no successor, and the other data element is a precursor and a successor. (The single head node, the only tail nodes; the middle node has a unique precursor, the only successor) tree structure: root node no precursor, multiple leaf nodes no successor, other elements of a precursor, multiple successors. (single root node; multiple leaf nodes; intermediate nodes have a single precursor, multiple successors)
Two-fork Tree
A tree structure that satisfies the following two conditions is called a two-fork tree (binary trees):
(1) The degree of each node is not more than 2;
(2) the child node order of each node cannot be reversed at any point. even if only one subtrees tree is to be differentiated, it indicates whether it is a left subtree or a right sub-tree. This is the main difference between the two tree and the tree.
There are 5 different forms of binary tree
The nature of binary tree
Property 1: There are at most 2^ (i-1) nodes (I>=1) on the first layer of the binary tree.
This property is proved by inductive method.
(1) When I=1, 2^ (i-1) =2^0 = 1, the proposition is established.
(2) Assuming that the proposition is i=k, that is, the K-layer has a maximum of 2^ (k-1) nodes;
(3) from the induction hypothesis, because the degree of each node of the binary tree is the maximum of 2, so the largest node on the K+1 layer is the largest node on the K-layer twice times,
namely 2x2^ (k-1) =2^k=2^ (k+1)-1
The proposition has been proved.
Property 2: A two-tree with a depth of K has a maximum of 2^k-1 nodes (k≥1).
Proof: The maximum number of nodes of a two-fork tree with a depth of k is visible by the nature 1
Property 3: For any binary tree, if its terminal node number is n0, the degree of 2 of the node is N2, then n0=n2+1.
Proof: Set the total number of nodes on the two-fork tree n = n0 + n1 + n2 (1)
And the number of branches on the binary tree B = n1+2n2 (2)
and root nodes, the rest of the nodes have branches, that is, B = n-1.
Substituting (1) (2) for n0 = n2 + 1.
Two special types of two-fork trees: full two-tree and complete binary tree
Full two fork tree: a two-prong tree with a depth of K and a 2^k-1 node.
Complete binary tree: The n nodes contained in the tree correspond to the nodes one by one in the tree with a number 1 to n in the full two. (numbered rules are, from top to bottom, from left to right.) )
Property 4: The depth of a complete binary tree with n nodes is [log2 n]+1.
Proof: Assuming that the depth of this binary tree is k, it is obtained according to the definition of Nature 2 and the complete binary tree:
2^ (k-1) -1<n<=2^k-1 or 2^ (k-1) <=n<2^k
The logarithm is obtained: K-1 <= log2 n < k because k is an integer. So there are: k= "log2n" +1.
Property 5: If the node of a complete binary tree with n nodes is numbered sequentially (from 1th to log2n + 1, each layer from left to right), then to any node I (1<=i<=n), there are:
1) If i=1, then node I have no parents, is the root of the two fork tree, if i>1, then their parents are node "I/2".
2) If 2i>n, then node i is the leaf node, no left child; otherwise, the left child is the node 2i.
3) If 2i+1>n, then node I no right child, otherwise, the right child is a node 2i+1.
The relationship between the node of the complete binary tree and its left and right child nodes is shown.
The storage structure of binary tree
1) Sequential storage structure
Complete binary tree: stores each node element from left to right, using a contiguous set of storage units, sequentially from top to bottom. The value of the node that will be numbered I on the complete binary tree is stored in an array element with the subscript i-1. The relationship between nodes can be calculated from the formula.
General two-fork tree: Add some empty nodes to make a complete binary tree form, and then store it as described above.
Complete binary Tree Storage
Storage of single binary tree
Summarize:
1, complete binary tree with sequential storage saves space, access is also convenient;
2, the general binary tree with the order of storage, space is wasted, the worst case is right single branch two fork tree. (a single tree with a depth of k and only a K node requires a one-dimensional array of length 2^k-1)
2) binary tree chain storage method
A commonly used two-fork linked list and a triple-linked list to store structure nodes. Children or both parents are instructed by pointers
Sometimes the subscript of the array can be used to simulate the pointer, that is, the creation of three one-dimensional array data, lchild,rchild respectively the elements of the node and its left, right pointer field; The following is a two-tree representation of chained storage:
struct binode{ int data; data domain binode *lchild, *rchild; left and right child pointer } binode, *bitree;
Examples of binary tree list representations:
Traversing a binary tree and a clue two fork tree
Any non-empty two-fork tree that consists of three-part tree traversal is a process that accesses each node in the tree only once. Traversal can be thought of as placing all nodes on a single line, or a tree being linearly processed.
First Order traversal
Around the DLR root: access to root nodes, first-order traversal Zuozi, first-order traversal of the right sub-tree
If the binary tree is not empty
(1) Access to the root node;
(2) The first sequence traverses the left subtree;
(3) The first sequence traverses the right sub-tree;
If the binary tree is empty, end-the basic item (also called the terminating item)
If the binary tree is not empty--recursion
(1) Access to the root node;
(2) The first sequence traverses the left subtree;
(3) The first sequence traverses the right sub-tree;
The main process is recursive invocation, can also be implemented with a stack.
For the first-order traversal, the first time the blue cut through the node, is the sequence of traversal, and then again experience is not counted in.
typedefstructbinode{intData//data fieldsBinode *lchild, *rchild;//child hands left and right} binode, *Bitree;voidPreorder (Binode *root) { if(Root! =NULL) { //Accessing the root nodecout <<"First Order Traversal"<< root->data; Preorder (Root-lchild); Preorder (Root-rchild); }//End of If}
Non-recursive first-order traversal
Prioritize access to the root node, and then access the left child and right child, respectively, based on the order of the pre-order traversal access. That is, for any node, it can be regarded as a root node, so it is directly accessible, after access, if the left child is not empty, the same rules access its left subtree, and then access its right subtree when its left subtree is accessed. So the process is as follows:
For any node P:
1) Access the node P and the node p into the stack;
2) Determine whether the left child of the node P is empty, if it is empty, take the top node of the stack and perform a stack operation, and the right child of the top node of the stack is set to the current node p, loop to 1); If not empty, the left child of P is placed as the current node p;
3) until p is null and the stack is empty, the traversal ends.
//The key is when to access the location of the statementvoidpreorder (Bitree root) {//Initialize StackStack<bitree>nodes; Binode*p =Root; while(P! = NULL | |!Nodes.empty ()) { while(P! =NULL) { //sequential traversal of the root aroundcout << p->data; //into the stackNodes.push (P); //continue to movep = p->Lchild; } //p = = NULL if(!Nodes.empty ()) { //re-pointing to Pp =Nodes.top (); //out of the stackNodes.pop (); //go to right sub-treep = p->Rchild; } }}
the middle sequence traversal, post-order traversal and the first sequence traversal thought is basically similar , for the middle sequence traversal, the blue Shear head second passes through the node, is the traversal sequence, before and after again the experience is not counted into the sequence. For the post-order traversal, the third pass of the blue head of the node, is the sequence of traversal, the previous experience is not counted in.
Ldr left and right: Middle sequence traversal Zuozi, Access root node, middle sequence traversal right subtree
If the binary tree is not empty
(1) The middle sequence traverses the left subtree;
(2) Access to the root node;
(3) The middle sequence traverses the right sub-tree;
If the binary tree is empty, end-the basic item (also called the terminating item)
If the binary tree is not empty--recursion
(1) The middle sequence traverses the left subtree;
(2) Access to the root node;
(3) The middle sequence traverses the right sub-tree;
Middle order recursive traversal algorithm
void inorder (binode *root) { if (root = NULL) { inorder (root lchild); " First Order Traversal " << root->data; Inorder (Root-rchild); } // end of If}
Non-recursive traversal of the middle sequence, using stacks
//non-recursive sequential traversal of binary treevoidinorder (Bitree root) {//non-recursive in-sequence traversal (left and right)Stack<bitree> nodes;//Initialize Stack//indicator PointerBinode *p =Root; //Iterating through a binary tree while(P! = NULL | |!Nodes.empty ()) { while(P! =NULL) { //not empty on the stackNodes.push (P); //keep going until the Kongp = p->Lchild; } //need to determine null no, because the stack operation is required if(!Nodes.empty ()) { //make P point back to the top node of the stackp =Nodes.top (); //Access root node (stack top junction)cout << P->data <<" "; //use complete, ejectNodes.pop (); //Traverse Rightp = p->Rchild; } }//End of while}
lrd around: post-order traversal of Zuozi, the subsequent traversal of the right subtree, access to the root node
Post-order traversal sequence: Bdfgeca
// recursive follow-up traversal of binary tree void Lastorder (Bitree root) { if (root! = NULL) { Lastorder (root-lchild); Lastorder (Root,rchild); << root->data; }}
Similarly, there are non-recursive follow-through binary trees
In the post-order traversal, make sure that both the left child and the right child have been visited, and that the left child can access the root node after the right child visits. So for any node p, first put it into the stack. If p does not exist on the left child and right child, it can be accessed directly, or p has left child or right child, but the left child and right child have been visited, you can also directly access the node. In either case, the right child of P and the left child are placed in the stack, which ensures that the left child is accessed in front of the right child, and the left child and right child are accessed in front of the root node each time the top element of the stack is taken.
voidPostOrder3 (Bitree root)//non-recursive post-traversal{Stack<BiTree>nodes; //Current NodeBinode *cur; //node of the previous visitBinode *pre =NULL; //root node into the stackNodes.push (root); //Traverse left and right subtrees sequentially while(!Nodes.empty ()) {cur=Nodes.top (); //determine the situation of the child tree in the left and right cur nodes if((Cur->lchild = = NULL && Cur->rchild = = null) | |(Pre! = NULL && (pre = = Cur->lchild | | pre = cur->rchild))) { //If the current node has no child nodes or if the child has been visitedcout << cur->data; //out of the stackNodes.pop (); //Previous access node, pre tag node already visitedPre =cur; } Else { //the access order of the left and right, the key or the location of the ACCESS Statement!!! Must first write the right subtree, and then write the left subtree, the order can not be wrong//if the right sub-tree of the current node is not empty if(Cur->rchild! =NULL) {Nodes.push (cur-rchild); } //if the left sub-tree of the current node is not empty if(Cur->lchild! =NULL) {Nodes.push (cur-lchild); } } }}
Summary of binary tree traversal:
Regardless of the first order, the middle order, the second step traversal of the binary tree, the search route is the same: from the root node, counter-clockwise extension of the cross-tree outer edge of the movement, for each node through three times.
First-order traversal: accessed the first time it passes through a node. (ABCD)
Middle-order traversal: accessed the second time it passes through a node. (BADC)
Post-post traversal: accessed the third time through the node. (BDCA)
The storage method of binary tree and three kinds of recursive and non-recursive methods