Recursive Algorithms and non-Recursive Algorithms for Binary Tree first-order, middle-order, and post-order traversal, binary tree Recursion
First-order traversal: If the binary tree is empty, the operation is blank; otherwise, the root node is accessed; first, the left subtree is traversed; first, the right subtree is traversed.
Middle-order traversal: If the binary tree is empty, the operation is null; otherwise, the left subtree is traversed in the middle order; the root node is accessed; and The right subtree is traversed in the middle order.
Post-order traversal: If the binary tree is empty, the operation is null; otherwise, the left subtree is traversed in descending order; the right subtree is traversed in descending order; and the root node is accessed.
Binary linked list: the node in the linked list contains three fields: Data Field and left and right pointer field.
Triple linked list: adds a pointer field pointing to the parent node on the basis of the binary linked list.
The following code uses a binary linked list.
// Binary Tree binary linked list storage represents typedef char TElemType; typedef struct BiNode {TElemType data; struct BiNode * lchild, * rchild;} BiNode, * BiTree;
1.Generate Binary Tree
Nodes can be generated during the traversal process to establish a binary tree storage structure. The algorithm for creating a binary tree binary linked list in the first sequence is as follows:
/** Enter the node value (one character) in the binary tree in the First Order. The space character represents the empty tree and the binary tree T represented by the binary linked list is constructed. */Status CreatBiTree (BiTree * T) {char ch; scanf ("% c", & ch); // If the currently entered character is a space, (* T) point to the empty tree. If (ch = '') {(* T) = NULL;} else {if (! (* T) = (BiTree) malloc (sizeof (BiNode) exit (OVERFLOW); (* T)-> data = ch; // generate the root node CreatBiTree (& (* T)-> lchild); // construct the left subtree CreatBiTree (& (* T)-> rchild )); // construct the right subtree} return OK ;}
Assume that the input characters are ABC # DE # G # F ### (# indicates space), the generated binary tree is as follows:
2.Binary tree traversal Recursive Algorithm
A. Sequential Traversal
/** Uses the binary linked list storage structure. Visit is an application function for Data Element operations. * It first traverses the recursive algorithm of binary tree T and calls the Visit function for each data element. */Status PreOrderTraverse_Recursive (BiTree T, Status (* Visit) (TElemType e) {if (T) {if (Visit (T-> data )) if (PreOrderTraverse_Recursive (T-> lchild, Visit) if (PreOrderTraverse_Recursive (T-> rchild, Visit) return OK; return ERROR; // The function does not execute this step, no Error is returned. This is only written to avoid compilation warnings .} Elsereturn OK; // stop recursion when T is an empty tree .}
B. Sequential Traversal
Status InOrderTraverse_Recursive(BiTree T, Status(*Visit)(TElemType e)){if (T){if (InOrderTraverse_Recursive(T->lchild, Visit))if (Visit(T->data))if (InOrderTraverse_Recursive(T->rchild, Visit))return OK;return ERROR;}elsereturn OK;}
C. Post-order traversal
Status PostOrderTraverse_Recursive(BiTree T, Status(*Visit)(TElemType e)){if (T){if (PostOrderTraverse_Recursive(T->lchild, Visit))if (PostOrderTraverse_Recursive(T->rchild, Visit))if (Visit(T->data))return OK;return ERROR;}elsereturn OK;}
3.Binary tree traversal non-recursive algorithm
A. Sequential Traversal
/** Traverse Binary Trees in sequence, non-recursive algorithms. */Status PreOrderTraverse_NonRecursive (BiTree T, Status (* Visit) (TElemType e) {Stack * S; // the pointer to the Tree node is stored in Stack S. BiTree p; S = (Stack *) malloc (sizeof (Stack); InitStack (S); Push (S, T); // The root pointer is pushed to the Stack. While (! StackEmpty (S) {// obtain the top pointer of the stack. If the top pointer of the stack is not empty, access this node. And add the left subtree of the node to the stack. If (GetTop (S, & p) {if (! Visit (p-> data) return ERROR; Push (S, p-> lchild);} // The stack top pointer is null, it indicates that the Left or right subtree is empty. Else {Pop (S, & p); // empty pointer back to stack if (! StackEmpty (S) {Pop (S, & p); // unstack the accessed root node. At this time, the left subtree of the rollback node has been fully accessed. Push (S, p-> rchild); // stack the right subtree .}}} Return OK ;}
B. Sequential Traversal
/** Uses a binary linked list storage structure. Visit is an application function that operates on data elements. * It uses a non-recursive algorithm to traverse Binary Trees in a central order and calls Visit for each data element. */Status InOrderTraverse_NonRecursive (BiTree T, Status (* Visit) (TElemType e) {Stack * S; BiTree p; S = (Stack *) malloc (sizeof (Stack )); initStack (S); Push (S, T); // root pointer into Stack while (! StackEmpty (S) {// left to the end while (GetTop (S, & p) {Push (S, p-> lchild );} // empty pointer back stack Pop (S, & p); // access the node and step to the right if (! StackEmpty (S) {Pop (S, & p); if (! Visit (p-> data) return ERROR; Push (S, p-> rchild) ;}} return OK ;}
Or
/** Uses a binary linked list storage structure. Visit is an application function that operates on data elements. * It uses a non-recursive algorithm to traverse Binary Trees in a central order and calls Visit for each data element. */Status InOrderTraverse_NonRecursive_2 (BiTree T, Status (* Visit) (TElemType e) {Stack * S; BiTree p = T; S = (Stack *) malloc (sizeof (Stack); InitStack (S); while (p |! StackEmpty (S) {// The root pointer goes into the stack and traverses the left subtree if (p) {Push (S, p); p = p-> lchild ;} // return the root pointer to the stack, access the root node, and traverse the right subtree else {Pop (S, & p); if (! Visit (p-> data) return ERROR; p = p-> rchild;} return OK ;}
C. Post-order traversal
/** Post-order traversal of Binary Trees, non-recursive algorithms */Status PostOrderTraverse_NonRecursive (BiTree T, Status (* Visit) (TElemType e) {Stack * S; BiTree p, pre = NULL; // pre points to the last accessed node. S = (Stack *) malloc (sizeof (Stack); InitStack (S); Push (S, T); // root pointer into Stack while (! StackEmpty (S) {// obtain the top pointer of the stack. If the current node has a left subtree and the left subtree node is not the newly accessed node. If the current node has a right subtree and the right subtree node is not the accessed node. // Indicates that the tree node pointed to by the top pointer of the stack is not accessed, and the left and right subtree are not accessed. In this case, the left subtree of the node is pushed to the stack. If (GetTop (S, & p) & p-> lchild & pre! = P-> lchild &&! (P-> rchild & pre = p-> rchild) Push (S, p-> lchild); // if the right subtree of the top pointer of the stack exists, not accessed. Put the right subtree into the stack else if (p-> rchild & pre! = P-> rchild) Push (S, p-> rchild); // if both the left and right subtree have been accessed, the node will return to the stack and access the node. Update pre. Else {Pop (S, & p); if (! Visit (p-> data) return ERROR; pre = p ;}} return OK ;}
4. Test the complete code
/** Assume that the input character is ABC # DE # G # F ###. In actual input, # is replaced by space. */# Define _ CRT_SECURE_NO_WARNINGS # include <stdio. h> # include <malloc. h> # include <stdlib. h> typedef int Status; # define OK 1 # define ERROR 0 # define OVERFLOW-2 // Binary Tree binary linked list storage represents typedef char TElemType; typedef struct BiNode {TElemType data; struct BiNode * lchild, * rchild;} BiNode, * BiTree; // stack sequence storage structure # define STACK_INIT_SIZE 100 // storage space initial allocation # define STACKINCREMENT 10 // storage space allocation incremental typedef struct {BiTree * base; BiTree * t Op; int stacksize;} Stack; // function declaration Status InitStack (Stack * S); Status Push (Stack * S, BiTree p); Status Pop (Stack * S, biTree * p); Status GetTop (Stack * S, BiTree * p); Status StackEmpty (Stack * S); Status CreatBiTree (BiTree * T); Status PreOrderTraverse_Recursive (BiTree T, status (* Visit) (TElemType e); Status InOrderTraverse_Recursive (BiTree T, Status (* Visit) (TElemType e); Status PostOrderTraverse_Recursive (BiTre) E T, Status (* Visit) (TElemType e); Status PreOrderTraverse_NonRecursive (BiTree T, Status (* Visit) (TElemType e); Status InOrderTraverse_NonRecursive (BiTree T, status (* Visit) (TElemType e); Status InOrderTraverse_NonRecursive_2 (BiTree T, Status (* Visit) (TElemType e); Status PostOrderTraverse_NonRecursive (BiTree T, Status (* Visit) (TElemType e); Status PrintElement (TElemType e); int main () {BiTree T; CreatBiT Ree (& T); // PreOrderTraverse_Recursive (T, PrintElement); putchar ('\ n'); PreOrderTraverse_NonRecursive (T, PrintElement); putchar (' \ n '); // InOrderTraverse_Recursive (T, PrintElement); putchar ('\ n'); InOrderTraverse_NonRecursive (T, PrintElement); putchar (' \ n'); random (T, PrintElement ); putchar ('\ n'); // post-order PostOrderTraverse_Recursive (T, PrintElement); putchar (' \ n'); PostOrderTraverse _ NonRecursive (T, PrintElement); putchar ('\ n'); return 0;}/** enter the node values (one character) in the binary tree in the first order ), the space character represents the empty tree and the binary tree T represented by the binary linked list is constructed. */Status CreatBiTree (BiTree * T) {char ch; scanf ("% c", & ch); // If the currently entered character is a space, (* T) point to the empty tree. If (ch = '') {(* T) = NULL;} else {if (! (* T) = (BiTree) malloc (sizeof (BiNode) exit (OVERFLOW); (* T)-> data = ch; // generate the root node CreatBiTree (& (* T)-> lchild); // construct the left subtree CreatBiTree (& (* T)-> rchild )); // construct the right subtree} return OK;}/** uses the binary linked list storage structure. Visit is an application function for Data Element operations. * recursively traverses binary tree T, call the Visit function for each data element. */Status PreOrderTraverse_Recursive (BiTree T, Status (* Visit) (TElemType e) {if (T) {if (Visit (T-> data )) if (PreOrderTraverse_Recursive (T-> lchild, Visit) if (PreOrderTraverse_Recursive (T-> rchild, Visit) return OK; return ERROR; // The function does not execute this step, no Error is returned. This is only written to avoid compilation warnings .} Elsereturn OK; // stop recursion when T is an empty tree .} Status InOrderTraverse_Recursive (BiTree T, Status (* Visit) (TElemType e) {if (T) {if (InOrderTraverse_Recursive (T-> lchild, Visit )) if (Visit (T-> data) if (InOrderTraverse_Recursive (T-> rchild, Visit) return OK; return ERROR;} elsereturn OK;} Status PostOrderTraverse_Recursive (BiTree T, status (* Visit) (TElemType e) {if (T) {if (PostOrderTraverse_Recursive (T-> lchild, Visit) if (PostOrderTraverse_Recursive (T-> rc Hild, Visit) if (Visit (T-> data) return OK; return ERROR;} elsereturn OK;}/** traverses Binary Trees in sequence, non-recursive algorithms. */Status PreOrderTraverse_NonRecursive (BiTree T, Status (* Visit) (TElemType e) {Stack * S; // the pointer to the Tree node is stored in Stack S. BiTree p; S = (Stack *) malloc (sizeof (Stack); InitStack (S); Push (S, T); // The root pointer is pushed to the Stack. While (! StackEmpty (S) {// obtain the top pointer of the stack. If the top pointer of the stack is not empty, access this node. And add the left subtree of the node to the stack. If (GetTop (S, & p) {if (! Visit (p-> data) return ERROR; Push (S, p-> lchild);} // The stack top pointer is null, it indicates that the Left or right subtree is empty. Else {Pop (S, & p); // empty pointer back to stack if (! StackEmpty (S) {Pop (S, & p); // unstack the accessed root node. At this time, the left subtree of the rollback node has been fully accessed. Push (S, p-> rchild); // stack the right subtree .}}} Return OK;}/** uses the binary linked list storage structure. Visit is an application function that operates on data elements. * It is a non-recursive algorithm that traverses Binary Trees in ascending order, call the Visit function for each data element. */Status InOrderTraverse_NonRecursive (BiTree T, Status (* Visit) (TElemType e) {Stack * S; BiTree p; S = (Stack *) malloc (sizeof (Stack )); initStack (S); Push (S, T); // root pointer into Stack while (! StackEmpty (S) {// left to the end while (GetTop (S, & p) {Push (S, p-> lchild );} // empty pointer back stack Pop (S, & p); // access the node and step to the right if (! StackEmpty (S) {Pop (S, & p); if (! Visit (p-> data) return ERROR; Push (S, p-> rchild) ;}} return OK;}/** uses a binary linked list storage structure, visit is an application function that operates on data elements. * A non-recursive algorithm that traverses Binary Trees in a central order and calls Visit for each data element. */Status InOrderTraverse_NonRecursive_2 (BiTree T, Status (* Visit) (TElemType e) {Stack * S; BiTree p = T; S = (Stack *) malloc (sizeof (Stack); InitStack (S); while (p |! StackEmpty (S) {// The root pointer goes into the stack and traverses the left subtree if (p) {Push (S, p); p = p-> lchild ;} // return the root pointer to the stack, access the root node, and traverse the right subtree else {Pop (S, & p); if (! Visit (p-> data) return ERROR; p = p-> rchild;} return OK;}/** traverse a binary tree in descending order, non-recursive algorithm */Status PostOrderTraverse_NonRecursive (BiTree T, Status (* Visit) (TElemType e) {Stack * S; BiTree p, pre = NULL; // pre points to the last accessed node. S = (Stack *) malloc (sizeof (Stack); InitStack (S); Push (S, T); // root pointer into Stack while (! StackEmpty (S) {// obtain the top pointer of the stack. If the current node has a left subtree and the left subtree node is not the newly accessed node. If the current node has a right subtree and the right subtree node is not the accessed node. // Indicates that the tree node pointed to by the top pointer of the stack is not accessed, and the left and right subtree are not accessed. In this case, the left subtree of the node is pushed to the stack. If (GetTop (S, & p) & p-> lchild & pre! = P-> lchild &&! (P-> rchild & pre = p-> rchild) Push (S, p-> lchild); // if the right subtree of the top pointer of the stack exists, not accessed. Put the right subtree into the stack else if (p-> rchild & pre! = P-> rchild) Push (S, p-> rchild); // if both the left and right subtree have been accessed, the node will return to the stack and access the node. Update pre. Else {Pop (S, & p); if (! Visit (p-> data) return ERROR; pre = p;} return OK;} // function Status PrintElement (TElemType e) called when traversing data elements) {putchar (e); return OK;} // initialize the Stack Status InitStack (Stack * s) {s-> base = (BiTree *) malloc (sizeof (BiTree) * STACK_INIT_SIZE); s-> top = s-> base; s-> stacksize = STACK_INIT_SIZE; return OK;} // obtain the Status GetTop (Stack * s, biTree * c) {if (StackEmpty (s) return ERROR; * c = * (s-> top-1); return OK ;} // determine whether the Stack is empty. Status StackEmpty (Stack * s) {if (s-> base = s-> top) return OK; return ERROR ;} // Stack Status Push (Stack * s, BiTree c) {// if there is not enough space, increase space allocation if (s-> top-s-> base> = s-> stacksize) {s-> base = (BiTree *) realloc (s-> base, sizeof (BiTree) * (s-> stacksize + STACKINCREMENT); s-> stacksize = s-> stacksize + STACKINCREMENT;} * (s-> top ++) = c; return OK;} // Stack Status Pop (Stack * s, BiTree * c) {if (StackEmpty (s) return ERROR; * c = * (-- s-> top); return OK ;}
5. Test Results
Note: The tree generated in the program is the tree in
Recursive Algorithms for binary tree traversal (C program, in ascending or descending order)
//************************************** *********************
// Header file
# Include <stdio. h>
# Include <stdlib. h>
//************************************** *********************
// Macro definition
# Define OK 1
# Define ERROR 0
# Define OVERFLOW 0
//************************************** *********************
Typedef struct BiTNode {
// Binary Tree binary linked list Storage Structure
Char data;
Struct BiTNode * lChild, * rChild;
} BiTNode, * BiTree;
//************************************** *********************
Int CreateBiTree (BiTree & T ){
// Enter the value of the Tree node in the binary tree in the FIFO order. A space indicates the empty tree.
// Construct the binary tree T represented by the binary linked list
Char ch;
Fflush (stdin );
Scanf ("% c", & ch );
If (ch = '') T = NULL;
Else {
If (! (T = (BiTNode *) malloc (sizeof (BiTNode ))))
Return (OVERFLOW );
T-> data = ch;
CreateBiTree (T-> lChild );
CreateBiTree (T-> rChild );
}
Return (OK );
}
//************************************** *******************
Void PreOrderTraverse (BiTree T ){
// Uses the binary linked list Storage Structure and first traverses the binary tree recursive algorithm
If (T ){
Printf ("% c", T-> data );
PreOrderTraverse (T-> lChild );
PreOrderTraverse (T-> rChild );
}
}
/*************************************** ********************
Void InOrderTraverse (BiTree T ){
// Uses the binary linked list storage structure and the recursive algorithm for Traversing binary trees in the central order
If (T ){
InOrderTraverse (T-> lChild );
... The remaining full text>
Write a program to implement the first-order traversal of Binary trees, the middle-order traversal, the various recursive and non-recursive algorithms for the later-order traversal, and the hierarchical Traversal Algorithms
The main. cpp file code is as follows:
# Include <malloc. h> // malloc ()
# Include <stdio. h> // standard input/output header file, including EOF (= ^ Z or F6) and NULL
# Include <stdlib. h> // atoi (), exit ()
# Include <math. h> // header file of mathematical functions, including floor (), ceil (), abs (), etc.
# Define ClearBiTree DestroyBiTree // The operation for clearing a binary tree is the same as that for destroying a binary tree
Typedef struct BiTNode
{
Int data; // node Value
BiTNode * lchild, * rchild; // left/right child pointer
} BiTNode, * BiTree;
Int Nil = 0; // set the integer to 0 as null
Void visit (int e)
{Printf ("% d", e); // output in integer format
}
Void InitBiTree (BiTree & T)
{// Operation result: Create an empty binary tree T
T = NULL;
}
Void CreateBiTree (BiTree & T)
{// Algorithm 6.4: Enter the value of the node in the binary tree in the FIFO order (which can be a string or integer and defined in the main process ),
// Construct the binary tree T represented by the binary linked list. The Nil variable indicates the empty (child) tree. Modify
Int number;
Scanf ("% d", & number); // enter the node Value
If (number = Nil) // The Node value is null.
T = NULL;
Else // The Node value is not empty
{T = (BiTree) malloc (sizeof (BiTNode); // generate the root node
If (! T)
Exit (OVERFLOW );
T-> data = number; // assign the value to the node indicated by T.
CreateBiTree (T-> lchild); // recursively construct the left subtree
CreateBiTree (T-> rchild); // recursively constructs the right subtree
}
}
Void DestroyBiTree (BiTree & T)
{// Initial condition: the binary tree T exists. Operation Result: Destroy binary tree T
If (T) // non-empty tree
{DestroyBiTree (T-> lchild); // recursively destroys the left subtree. If no left subtree exists, no operation is performed.
DestroyBiTree (T-> rchild); // recursively destroys the right subtree. If no right subtree exists, no operation is performed.
Free (T); // release the root node
T = NULL; // NULL pointer assigned 0
}
}
Void PreOrderTraverse (BiTree T, void (* Visit) (int ))
{// Initial condition: binary tree T... remaining full text>