Algorithmic Binary Tree Various Traversals

Posted by Grunge on Wed, 15 May 2019 05:40:05 +0200

               

Tree structure is an important non-linear data structure, among which trees and binary trees are the most common.

A binary tree is an ordered tree with at most two subtrees per node.The root of a subtree is often called a left subtree and a right subtree.Binary trees are often used as binary lookup trees and binary heaps or as binary sort trees.Each node of a binary tree has at most two subtrees (there are no nodes with a degree greater than 2). The subtrees of a binary tree have left-right divisions and the order cannot be reversed.A binary tree with a depth of K has at most 2^(k) -1 nodes; a binary tree with a depth of K has at most 2^(k) -1 nodes; for any binary tree T, if its terminal node number (i.e. leaf node number) is n0 and its degree of 2 is n2, then n0 = n2 + 1.

The chain storage structure of a binary tree is an important data structure, which is defined as follows:

//Binary tree node typedef struct BiTNode{//data char data; //left child pointer struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;


Binary tree creation:

By reading in a string, the algorithm for building a binary tree is as follows:

//Create binary tree int CreateBiTree (BiTree &T) {char data by sequential creation binary tree int CreateBiTree (BiTree &T) {char data; //Enter binary tree node values (one character),'#'denotes empty tree scanf ('%c', &data); if(data =='#') {data =='\#') {T = NULL;} else{T = (BiTree) malloc malloc (sizeof BiTNode); //Generate root node T->data = T->data; //data = data = Left subtree construction BiteCreateCreate BiTree, BiteCreateCreateCreate BiTreTree (T->lchild)); //Construct Right Subtree CreateBiTree (T->rchild);} return 0;}

Traversal of a binary tree:

Traversing is one of the most basic operations of a tree. Traversing a binary tree means traversing all the nodes of a binary tree according to certain rules and order so that each node is visited once and only once.Since a binary tree is a non-linear structure, traversing a tree essentially converts its nodes into a linear sequence to represent them.

Recursive algorithm:

//Output void Visit(BiTree T) {if (T->data!='#') {if (T->data!='#'{printf ('%c', T->data);}}//Priorit traversal void PreOrder(BiTree T) {if (T!== NULL) {////Access root node Visit(T); //Access left child node PrevoOrder (T->lchild); //Access right child node PreOrder (T->\#### {printftf'%c "%c", T->\####;}}///InInInvoid traversal traversal Order (BiTree T) {if (T!= NULL) {//access left child node]InOrder (T->lchild); //Access Root Node Visit(T); //Access Right Child Node InOrder (T->rchild);}}//PostOrder (BiTree T){if (T!= NULL){//Access Left Child Node PostOrder (T->lchild); //Access Right Child Node PostOrder (T->rchild); //Access Root Node Visit(T);}

Non-recursive algorithm:

<1>Sequential traversal:

[Ideas]: After accessing T->data, T is put on the stack and left subtree is traversed; when left subtree is traversed and returned, the top element of stack should be T, then the right subtree of T is traversed first.

/* The idea of traversing in order (non-recursive): after accessing T->data, T is put on the stack and left subtree is traversed; when the left subtree is traversed and returned, the top element of the stack should be T, then the right subtree of T is traversed in order.*/void PreOrder2(BiTree T)stack<BiTree> stack//p is a traversal pointer BiTree p = T; //Loop when stack is not empty or p is not empty while(p || !stack.empty()){  if(p != NULL){   //Store on Stack   stack.push(p);   //Access Root Node   printf("%c ",p->data);   //Traversing Left Subtree   p = p->lchild;  }  else{   //Unstack   p = stack.top();   stack.pop();   //Access right subtree   p = p->rchild;  } }//while}


<2>Intermediate traversal

[Ideas]: T is to traverse the root pointer of a tree. Intermediate traversal requires that after traversing the left subtree, access the root and then traverse the right subtree.
First put T on the stack and traverse the left subtree; when the left subtree is traversed and returned, the top element of the stack should be T, go out of the stack, access T->data, and then traverse the right subtree of T in middle order.

void InOrder2(BiTree T)stack<BiTree> stack//p is a traversal pointer BiTree p = T; //Loop when stack is not empty or p is not empty while(p || !stack.empty()){  if(p != NULL){   //Store on Stack   stack.push(p);   //Traversing Left Subtree   p = p->lchild;  }  else{   //Unstack, access root node   p = stack.top();   printf("%c ",p->data);   stack.pop();   //Access right subtree   p = p->rchild;  } }//while}

<3>Post-order traversal

[Ideas]: T is to traverse the root pointer of a tree, and post-order traversal requires that the root be accessed after the left and right subtrees have been traversed.You need to determine whether the left and right subtrees of the root node have been traversed.

//Post-sequential traversal (non-recursive) typedef struct BiTNodePost{BiTree biTree; char tag;}BiTNodePost,*BiTreePost;void PostOrder2(BiTree T) {stack<BiTreePost> stack; //p is the traversal pointer BiTree p = T; BiTreePost BT; //stack is not empty or P is not empty or a p is not empty periodic loop while (p!= NULL | | stack. empty () {stack empty y () {//left subtree //while tree (p //while) traversing P (= BiTreePost > BiTreePost > stack!= NULL) {BT = (BiTreePost)malloc(sizeof(BiTNodePost));;;; BT->biTree = p; / BT->biTree = p; // Visited left subtree: BT->tag ='L'; stack.push(BT); / stack.push(BT); / P = p->lchild;} /// left and right subtree access completed accessing the root node: while(! Stack.empty() && (stack.top() - >tag =='R') {stack.top()); / stack//backstack; / stack stack.pop.BT ();; / stack pop pop pop-pop-pop-BT-();; "biTree;" printf ("%c", BT->biTree->data);"} //Traverse the right subtree if (!Stack.empty(){BT = stack.top(); //Accessed the right subtree BT->tag ='R'; * P = BT->biTree; * P = p->rchild;} //while}


<4>Hierarchical traversal

[Ideas]: Access each node layer by layer from top to bottom and from left to right, using queues during hierarchical traversal.

//Hierarchtraverse void LevelOrder(BiTree T) {BiTree p = T; //queue queue <BiTree> queue; //queue <BiTree> queue; //root node queue.push(p); //queue.push(p); //queue does not empty loop while(!queue.empty()) {///header element quequeued p = queue.front(); //access the printf printf ("%c", p->data) //printftf ("%c", p->data); //quiqueue queue.queue queue queue queue queue queue queue queue queue queue (); //pop pop pop Left Subtree EntryF (p->lchild!= NULL) {queue.push (p->lchild);} //right subtree is not empty, bring right subtree into queue if (p->rchild!= NULL) {queue.push (p->rchild);}}


Test cases:


Input:

ABC##DE#G##F###

Output:


Code:

#include<iostream>#include<stack>#include<queue>using namespace std;//Binary Tree Nodetypedef struct BiTNode{ //data char data; //Left and right child pointer struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;//Create Binary Tree in Sequenceint CreateBiTree(BiTree &T)char data; //Enter the values (one character) of the nodes in the binary tree in order of order,'#'denotes an empty tree scanf("%c",&data); if(data == '#'){  T = NULL; } else{  T = (BiTree)malloc(sizeof(BiTNode));  //Generate Root Node  T->data = data;  //Construct left subtree  CreateBiTree(T->lchild);  //Construct Right Subtree  CreateBiTree(T->rchild); } return 0;}//outputvoid Visit(BiTree T)if(T->data != '#'){  printf("%c ",T->data); }}//Preorder traversalvoid PreOrder(BiTree T)if(T != NULL){  //Access Root Node  Visit(T);  //Access left subnode  PreOrder(T->lchild);  //Access right subnode  PreOrder(T->rchild); }}//Intermediate traversal void InOrder(BiTree T){      if(T != NULL){          //Access left subnode         InOrder(T->lchild);          //Access Root Node         Visit(T);          //Access right child node         InOrder(T->rchild);      }  }  //Post-order traversalvoid PostOrder(BiTree T)if(T != NULL){  //Access left subnode  PostOrder(T->lchild);  //Access right subnode  PostOrder(T->rchild);  //Access Root Node  Visit(T); }}/* The idea of traversing in order (non-recursive): after accessing T->data, T is put on the stack and left subtree is traversed; when the left subtree is traversed and returned, the top element of the stack should be T, then the right subtree of T is traversed in order.*/void PreOrder2(BiTree T)stack<BiTree> stack//p is a traversal pointer BiTree p = T; //Loop when stack is not empty or p is not empty while(p || !stack.empty()){  if(p != NULL){   //Store on Stack   stack.push(p);   //Access Root Node   printf("%c ",p->data);   //Traversing Left Subtree   p = p->lchild;  }  else{   //Unstack   p = stack.top();   stack.pop();   //Access right subtree   p = p->rchild;  } }//while}/* Intermediate traversal (non-recursive) idea: T is to traverse the root pointer of a tree. Intermediate traversal requires that after traversing the left subtree, access the root and then traverse the right subtree.First put T on the stack and traverse the left subtree; when the left subtree is traversed and returned, the top element of the stack should be T, go out of the stack, access T->data, and then traverse the right subtree of T in middle order.*/void InOrder2(BiTree T)stack<BiTree> stack//p is a traversal pointer BiTree p = T; //Loop when stack is not empty or p is not empty while(p || !stack.empty()){  if(p != NULL){   //Store on Stack   stack.push(p);   //Traversing Left Subtree   p = p->lchild;  }  else{   //Unstack, access root node   p = stack.top();   printf("%c ",p->data);   stack.pop();   //Access right subtree   p = p->rchild;  } }//while}//Post-order traversal (non-recursive)typedef struct BiTNodePost{ BiTree biTree; char tag;}BiTNodePost,*BiTreePost;void PostOrder2(BiTree T)stack<BiTreePost> stack//p is a traversal pointer BiTree p = T; BiTreePost BT; //Loop when stack is not empty or p is not empty while(p != NULL || !stack.empty()){  //Traversing Left Subtree  while(p != NULL){   BT = (BiTreePost)malloc(sizeof(BiTNodePost));   BT->biTree = p;   //Visited left subtree   BT->tag = 'L';   stack.push(BT);   p = p->lchild;  }  //Left and right subtrees complete accessing the root node  while(!stack.empty() && (stack.top())->tag == 'R'){   BT = stack.top();   //Unstack   stack.pop();   printf("%c ",BT->biTree->data);  }  //Traversing right subtree  if(!stack.empty()){   BT = stack.top();   //Right subtree visited   BT->tag = 'R';   p = BT->biTree;   p = p->rchild;  } }//while}//level traversalvoid LevelOrder(BiTree T){ BiTree p = T; //queue queue<BiTree> queue//Root node enqueued queue.push(p); //Queue not empty loop while(!queue.empty()){  //Counter Element Queued  p = queue.front();  //Accessing the node pointed to by p  printf("%c ",p->data);  //Exit Queue  queue.pop();  //Left subtree not empty, join left subtree  if(p->lchild != NULL){   queue.push(p->lchild);  }  //The right subtree is not empty, join the right subtree  if(p->rchild != NULL){   queue.push(p->rchild);  } }}int main(){ BiTree T; CreateBiTree(T); printf("Sequential traversal:\n"); PreOrder(T); printf("\n"); printf("Preorder traversal(non-recursive): \n"); PreOrder2(T); printf("\n"); printf("Intermediate traversal:\n"); InOrder(T); printf("\n"); printf("Intermediate traversal(non-recursive): \n"); InOrder2(T); printf("\n"); printf("Post-order 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;}


New Edition: Click to open the link



           

Topics: Programming