Tree structure is an important non-linear data structure, which is most frequently used by trees and Binary Trees.
A binary tree is an ordered tree with a maximum of two Subtrees at each node. Generally, the root of a subtree is called left subtree and right subtree ). Binary Trees are often used as binary search trees, binary heap trees, or binary sorting trees. Each node of a binary tree has at most two Subtrees (nodes with no degree of presence greater than 2). the Subtrees of a binary tree have left and right points, and the order cannot be reversed. The I-layer of a binary tree has at most 2 I-1 nodes, and the K-depth binary tree has at most 2 ^ (k)-1 nodes; for any binary tree T, if the number of terminal knots (that is, the number of leaf knots) is N0 and the number of knots whose degree is 2 is N2, N0 = n2 + 1.
The chain storage structure of a binary tree is an important data structure. Its format is defined as follows:
// Binary Tree node typedef struct bitnode {// data char data; // left and right child pointer struct bitnode * lchild, * rchild;} bitnode, * bitree;
Create a binary tree:
By reading a string, the algorithm for creating a binary tree is as follows:
// Create a binary tree int createbitree (bitree & T) {char data; // input the node value (one character) in the binary tree in the first order ), '#' indicates the empty tree scanf ("% C", & data); If (Data = '#') {T = NULL;} else {T = (bitree) malloc (sizeof (bitnode); // generate the root node T-> DATA = data; // construct the left subtree createbitree (t-> lchild ); // construct the right subtree createbitree (t-> rchild);} return 0 ;}
Binary tree traversal:
Traversal is one of the most important operations on the tree. The so-called traversal of a binary tree is to traverse all the nodes of the Binary Tree according to certain rules and order, so that each node is asked once, and is only asked once by the hacker. Because Binary Trees are non-linear structures, tree traversal essentially converts each node of a binary tree into a linear sequence.
Recursive Algorithm:
// Output void visit (bitree t) {If (t-> data! = '#') {Printf ("% C", T-> data) ;}}// first traverse void preorder (bitree t) {If (T! = NULL) {// supervisor asks the root node visit (t); // supervisor asks the left subnode preorder (t-> lchild ); // else ask the right subnode preorder (t-> rchild) ;}// traverse void inorder (bitree t) {If (T! = NULL) {// The cursor asks the left subnode inorder (t-> lchild); // The cursor asks the root node visit (t ); // else ask the right subnode inorder (t-> rchild) ;}// traverse void postorder (bitree t) {If (T! = NULL) {// The cursor asks the left subnode postorder (t-> lchild); // The cursor asks the right subnode postorder (t-> rchild ); // configure the root node visit (t );}}
Non-recursive algorithms:
<1> sequential traversal:
[Idea]: After the hacker asks T-> data, he puts T into the stack and traverses the left subtree. When the left subtree returns, the top element of the stack should be t, and the stack goes out, then, traverse the right subtree of T in sequence.
/* Method of first-order traversal (non-recursion): After the operator asks T-> data, t is loaded into the stack and the left subtree is traversed. When the left subtree is returned, the top element of the stack should be T. The stack goes out, and then the right subtree of T is traversed in sequence. */Void preorder2 (bitree t) {stack <bitree> stack; // P is the traversal pointer bitree P = T; // loop while (p |! Stack. Empty () {If (P! = NULL) {// save to stack. push (p); // send a question to the root node printf ("% C", p-> data); // traverse the left subtree P = p-> lchild ;} else {// stack rollback P = stack. top (); stack. pop (); // The right subtree P = p-> rchild;} // while}
<2> ordinal Traversal
[Idea]: T is the root pointer of the tree to be traversed. The central traversal requires that after the left subtree is traversed, the root be asked, and then the right subtree be traversed.
First, t is added to the stack, and the left subtree is traversed. When the left subtree is returned, the top element of the stack should be T. When the left subtree is traversed, T-> data is asked, traverse the right subtree of T in the middle order.
Void inorder2 (bitree t) {stack <bitree> stack; // P is the traversal pointer bitree P = T; // loop while (p |! Stack. Empty () {If (P! = NULL) {// save to stack. push (p); // traverse the left subtree P = p-> lchild;} else {// return stack, then ask the root node P = stack. top (); printf ("% C", p-> data); stack. pop (); // The right subtree P = p-> rchild;} // while}
<3> post-order traversal
[Idea]: T is the root pointer of the tree to be traversed. Post-order traversal requires that the root be asked after the left and right subtree is traversed. We need to infer whether the left and right subtree of the root node have been traversed.
// Post-order traversal (non-recursive) typedef struct bitnodepost {bitree; char tag;} bitnodepost, * bitreepost; void postorder2 (bitree t) {stack <bitreepost> stack; // P is the traversal pointer bitree P = T; bitreepost Bt; // loop while (P! = NULL |! Stack. Empty () {// traverse the left subtree while (P! = NULL) {bt = (bitreepost) malloc (sizeof (bitnodepost); Bt-> bitree = P; // The cursor asks the left subtree Bt-> tag = 'l '; stack. push (BT); P = p-> lchild;} // The left and right subtree when the left and right sides of the subtree are asked to complete the while (! Stack. empty () & (stack. top ()-> tag = 'R') {bt = stack. top (); // stack rollback. pop (); Bt-> bitree; printf ("% C", BT-> bitree-> data);} // traverse the right subtree if (! Stack. empty () {bt = stack. top (); // The right subtree Bt-> tag = 'R'; P = Bt-> bitree; P = p-> rchild ;}} // while}
<4> hierarchical Traversal
[Idea]: In the order from top to bottom and from left to right, each node is asked layer by layer. A queue is required during layered traversal.
// Traverse the void levelorder (bitree t) {bitree P = T; // queue <bitree> queue; // enter the queue as the root node. push (p); // The queue is not empty loop while (! Queue. empty () {// The opponent element leaves the queue P = queue. front (); // The vertex where P points to printf ("% C", p-> data); // exit the queue. pop (); // leave the left subtree empty. Join the left subtree if (p-> lchild! = NULL) {queue. Push (p-> lchild) ;}// the right subtree is not empty. The right subtree is queued if (p-> rchild! = NULL) {queue. Push (p-> rchild );}}}
Example:
Input:
ABC ## de # G ## F ###
Output:
Code:
# Include <iostream> # include <stack> # include <queue> using namespace STD; // Binary Tree node typedef struct bitnode {// data char data; // left and right child pointer struct bitnode * lchild, * rchild;} bitnode, * bitree; // create a binary tree int createbitree (bitree & T) {char data in sequence; // enter the node value (one character) in the binary tree in the first order, '#' indicates the empty tree scanf ("% C", & data ); if (Data = '#') {T = NULL;} else {T = (bitree) malloc (sizeof (bitnode )); // generate the root node T-> DATA = data; // construct the left subtree createbitree (t-> lchild); // construct the right subtree createb Itree (t-> rchild);} return 0;} // output void visit (bitree t) {If (t-> data! = '#') {Printf ("% C", T-> data) ;}}// first traverse void preorder (bitree t) {If (T! = NULL) {// supervisor asks the root node visit (t); // supervisor asks the left subnode preorder (t-> lchild ); // else ask the right subnode preorder (t-> rchild) ;}// traverse void inorder (bitree t) {If (T! = NULL) {// The cursor asks the left subnode inorder (t-> lchild); // The cursor asks the root node visit (t ); // else ask the right subnode inorder (t-> rchild) ;}// traverse void postorder (bitree t) {If (T! = NULL) {// The cursor asks the left subnode postorder (t-> lchild); // The cursor asks the right subnode postorder (t-> rchild ); // supervisor asks the root node visit (t);}/* The first-order traversal (non-recursive) idea: After the hacker asks T-> data, t is added to the stack, traverse the left subtree. When the left subtree is returned, the top element of the stack should be t, and the right subtree of T will be traversed first. */Void preorder2 (bitree t) {stack <bitree> stack; // P is the traversal pointer bitree P = T; // loop while (p |! Stack. Empty () {If (P! = NULL) {// save to stack. push (p); // send a question to the root node printf ("% C", p-> data); // traverse the left subtree P = p-> lchild ;} else {// stack rollback P = stack. top (); stack. pop (); // locate the right subtree P = p-> rchild ;}/// while}/* In-order traversal (non-recursion) idea: T is the root pointer of the tree to be traversed. The central traversal requires that after the left subtree is traversed, the worker asks the root and then traverses the right subtree. First, t is added to the stack, and the left subtree is traversed. When the left subtree is returned, the top element of the stack should be T. When the left subtree is traversed, T-> data is asked, traverse the right subtree of T in the middle order. */Void inorder2 (bitree t) {stack <bitree> stack; // P is the traversal pointer bitree P = T; // loop while (p |! Stack. Empty () {If (P! = NULL) {// save to stack. push (p); // traverse the left subtree P = p-> lchild;} else {// return stack, then ask the root node P = stack. top (); printf ("% C", p-> data); stack. pop (); // ask the right subtree P = p-> rchild ;}/// while} // post-order traversal (non-recursive) typedef struct bitnodepost {bitree; char tag;} bitnodepost, * bitreepost; void postorder2 (bitree t) {stack <bitreepost> stack; // P is the traversal pointer bitree P = T; bitreepost Bt; // loop while (P! = NULL |! Stack. Empty () {// traverse the left subtree while (P! = NULL) {bt = (bitreepost) malloc (sizeof (bitnodepost); Bt-> bitree = P; // The cursor asks the left subtree Bt-> tag = 'l '; stack. push (BT); P = p-> lchild;} // The left and right subtree when the left and right sides of the subtree are asked to complete the while (! Stack. empty () & (stack. top ()-> tag = 'R') {bt = stack. top (); // stack rollback. pop (); Bt-> bitree; printf ("% C", BT-> bitree-> data);} // traverse the right subtree if (! Stack. empty () {bt = stack. top (); // The right subtree Bt-> tag = 'R'; P = Bt-> bitree; P = p-> rchild ;}} // while} // traverse void levelorder (bitree t) {bitree P = T; // queue <bitree> queue; // enter the queue as the root node. push (p); // The queue is not empty loop while (! Queue. empty () {// The opponent element leaves the queue P = queue. front (); // The vertex where P points to printf ("% C", p-> data); // exit the queue. pop (); // leave the left subtree empty. Join the left subtree if (p-> lchild! = NULL) {queue. Push (p-> lchild) ;}// the right subtree is not empty. The right subtree is queued if (p-> rchild! = NULL) {queue. push (p-> rchild) ;}} int main () {bitree t; createbitree (t); printf ("sequential traversal: \ n "); preorder (t); printf ("\ n"); printf ("sequential traversal (non-recursive): \ n"); preorder2 (t ); printf ("\ n"); printf ("sequential traversal: \ n"); inorder (t); printf ("\ n "); printf ("sequential traversal (non-recursive): \ n"); inorder2 (t); printf ("\ n"); printf ("sequential traversal: \ n "); postorder (t); printf ("\ n"); printf ("post-order traversal (non-recursive): \ n"); postorder2 (t ); printf ("\ n"); printf ("hierarchical traversal: \ n"); levelorder (t); printf ("\ n"); Return 0 ;}
Binary tree traversal of Algorithms