# Traversal of binary tree

Time：2020-9-28

The traversal methods of binary tree include pre order, middle order, post order, hierarchy and Morris traversal.

``````Morris traverses the binary tree and marks the current node as cur
Cur has no left child:
Cur moves to the right child
Cur has left children:
Find the rightmost node of the left subtree of cur and mark it as rightmost
The right child pointer of rightmost points to null, and cur moves to the left child
Rightmost's right child pointer points to cur, and cur moves to the right child``````

Preorder traversal: recursive implementation
``````void preorderRecursionTraversal( NodeBinaryTree *root ) {
if( root == NULL ) {
return;
}
printf( "%d, ", root->val );
preorderRecursionTraversal( root->left, a, aSize );
preorderRecursionTraversal( root->right, a, aSize );
}``````
Preorder traversal: iterative implementation
``````#define NEW_STACK( s, capacity ) ({                             \
*s = malloc( sizeof(**s) + sizeof((*s)->a[0]) * capacity ); \
*s->t = 0; (*s)->c = capacity;                              \
})
#define PUSH_STACK( s, d ) ({ s->a[s->t++] = d; })
#define POP_STACK( s, d ) ({ *d = s->a[--s->t]; })
#define EMPTY_STACK( s ) (s->t < 1)
#define FULL_STACK( s ) (s->t >= s->c)
#define DEL_STACK( s ) ({ if( s != NULL && *s != NULL ) { free( *s ); *s = NULL; } })

typedef struct Stack {
int c;
int t;
void *a[0];
} Stack;

void preorderIterativeTraversal( NodeBinaryTree *root ) {
Stack *s = NULL;

if( root != NULL ) {
NEW_STACK( &s, 10000 );
PUSH_STACK( s, root );
}
while( !EMPTY_STACK( s ) ) {
POP_STACK( s, &root );
printf( "%d, ", root->val );
if( root->right != NULL ) {
PUSH_STACK( s, root->right );
}
if( root->left != NULL ) {
PUSH_STACK( s, root->left );
}
}
DEL_STACK( &s );
}``````
Preorder traversal: Morris implementation
``Only the first arriving node is processed``
``````void preorderMorrisTraversal( NodeBinaryTree *root ) {
while( root != NULL ) {
if( root->left != NULL ) {
NodeBinaryTree *rightmost = root->left;
while( rightmost->right != NULL && rightmost->right != root ) {
//The rightmost node of the left subtree of the cur node
rightmost = rightmost->right;
}
if( rightmost->right != NULL ) {
rightmost->right = NULL;
root = root->right;
} else {
//The rightmost node of the left subtree of cur node has not been modified, which indicates that it is the first time to reach cur node
printf( "%d, ", root->val );
rightmost->right = root;
root = root->left;
}
} else {
//Cur node has no subtree
printf( "%d, ", root->val );
root = root->right;
}
}
}``````

Middle order traversal: recursive implementation
``````void inorderRecursionTraversal( NodeBinaryTree *root ) {
if( root == NULL ) {
return;
}
inorderRecursionTraversal( root->left );
printf( "%d, ", root->val );
inorderRecursionTraversal( root->right );
}``````
Middle order traversal: iterative implementation
``````#define NEW_STACK( s, capacity ) ({                             \
*s = malloc( sizeof(**s) + sizeof((*s)->a[0]) * capacity ); \
*s->c = capacity;                                           \
*s->t = 0;                                                  \
})
#define PUSH_STACK( s, d )  ({ s->a[s->t++] = d; })
#define POP_STACK( s, d )   ({ *d = s->a[--s->t]; })
#define PEEK_STACK( s, d )  ({ *d = s->a[s->t - 1]; })
#define SIZE_STACK( s )     (s->t)
#define EMPTY_STACK( s )    (s->t < 1)
#define FULL_STACK( s )     (s->t >= s->c)
#define CLEAR_STACK( s )    ({ s->t = 0; })
#define DEL_STACK( s )      ({ if( s != NULL && *s != NULL ) { free( *s ); *s = NULL; } })

typedef struct Stack {
int c;
int t;
void *a[0];
} Stack;

void inorderIterativeTraversal( NodeBinaryTree *root ) {
Stack *s = NULL;

NEW_STACK( &s, 10000 );
#if 0
while( root != NULL || !EMPTY_STACK( s ) ) {
if( root != NULL ) {
PUSH_STACK( s, root );
root = root->left;
} else {
POP_STACK( s, &root );
printf( "%d, ", root->val );
root = root->right;
}
}
#else
while( root != NULL || !EMPTY_STACK( s ) ) {
while( root != NULL ) {
PUSH_STACK( s, root );
root = root->left;
}
POP_STACK( s, &root );
printf( "%d, ", root->val );
root = root->right;
}
#endif
DEL_STACK( &s );
}``````
Middle order traversal: Morris implementation
``Only nodes without left subtree and nodes arriving the second time are processed``
``````void inorderMorrisTraversal( NodeBinaryTree *root ) {
while( root != NULL ) {
if( root->left != NULL ) {
NodeBinaryTree *rightmost = root->left;
while( rightmost->right != NULL && rightmost->right != root ) {
//The rightmost node of the left subtree of the cur node
rightmost = rightmost->right;
}
if( rightmost->right != NULL ) {
//The left child and rightmost node of cur node has been modified, indicating that it is the second time to reach cur node,
//That is, the left subtree of cur node has been processed
printf( "%d, ", root->val );
rightmost->right = NULL;
root = root->right;
} else {
rightmost->right = root;
root = root->left;
}
} else {
//Cur node has no left subtree
printf( "%d, ", root->val );
root = root->right;
}
}
}``````

Post order traversal: recursive implementation
``````void postorderRecursionTraversal( NodeBinaryTree *root ) {
if( root == NULL ) {
return;
}
postorderRecursionTraversal( root->left );
postorderRecursionTraversal( root->right );
printf( "%d, ", root->val );
}``````
Post order traversal: iterative implementation
``````#define NEW_STACK( s, capacity ) ({                             \
*s = malloc( sizeof(**s) + sizeof((*s)->a[0]) * capacity ); \
*s->c = capacity;                                           \
*s->t = 0;                                                  \
})
#define PUSH_STACK( s, d )  ({ s->a[s->t++] = d; })
#define POP_STACK( s, d )   ({ *d = s->a[--s->t]; })
#define PEEK_STACK( s, d )  ({ *d = s->a[s->t - 1]; })
#define SIZE_STACK( s )     (s->t)
#define EMPTY_STACK( s )    (s->t < 1)
#define FULL_STACK( s )     (s->t >= s->c)
#define CLEAR_STACK( s )    ({ s->t = 0; })
#define DEL_STACK( s )      ({ if( s != NULL && *s != NULL ) { free( *s ); *s = NULL; } })

typedef struct Stack {
int c;
int t;
void *a[0];
} Stack;

//Another implementation: using two stacks, the middle right left traversal is changed to the middle right left traversal, the middle right left procedure uses stack 1, and the left and right middle procedure uses stack 2
//Change the output place of the elements in the middle right and left procedure to push the output elements into stack 2,
//Finally, all the elements of stack 2 are ejected and output to get the left and right middle traversal sequence
void postorderIterativeTraversal( NodeBinaryTree *root ) {
NodeBinaryTree *lasttime = root;
Stack *s = NULL;

NEW_STACK( &s, 10000 );
if( root != NULL ) {
PUSH_STACK( s, root );
}
while( !EMPTY_STACK( s ) ) {
PEEK_STACK( s, &root );
if( root->left != NULL && root->left != lasttime && root->right != lasttime ) {
PUSH_STACK( s, root->left );
} else if( root->right != NULL && root->right != lasttime ) {
PUSH_STACK( s, root->right );
} else {
POP_STACK( s, &lasttime );
printf( "%d, ", lasttime->val );
}
}
DEL_STACK( &s );
}``````
Postorder traversal: Morris implementation
``````The first step is to process the right boundary node of the left subtree of the second arrival node in reverse order,
Finally, the right boundary nodes of the whole tree are processed in reverse order``````
``````static void reverseHandleRightBoundary( NodeBinaryTree *root ) {
NodeBinaryTree *p1 = NULL, *p2 = NULL, *p3 = NULL;

for( p2 = root, p1 = NULL; p2 != NULL; p2 = p3 ) {
p3 = p2->right;
p2->right = p1;
p1 = p2;
}
for( p2 = p1, p1 = NULL; p2 != NULL; p2 = p3 ) {
printf( "%d, ", p2->val );
p3 = p2->right;
p2->right = p1;
p1 = p2;
}
}

void postorderMorrisTraversal( NodeBinaryTree *root ) {
NodeBinaryTree *cur = root;

while( cur != NULL ) {
if( cur->left != NULL ) {
NodeBinaryTree *rightmost = cur->left;
while( rightmost->right != NULL && rightmost->right != cur ) {
rightmost = rightmost->right;
}
if( rightmost->right != NULL ) {
//The left child and the right node of cur node have been modified, indicating that it is the second time to come to cur node
rightmost->right = NULL;
//Reverse order processing cur node left subtree right boundary node
reverseHandleRightBoundary( cur->left );
cur = cur->right;
} else {
rightmost->right = cur;
cur = cur->left;
}
} else {
cur = cur->right;
}
}
//Finally, the right boundary nodes of the whole tree are processed in reverse order
reverseHandleRightBoundary( root );
}``````

Hierarchical traversal: iterative implementation
``````#define NEW_QUEUE( q, capacity ) ({                             \
*q = malloc( sizeof(**q) + sizeof((*q)->a[0]) * capacity ); \
*q->c = capacity;                                           \
*q->s = 0;                                                  \
*q->h = 0;                                                  \
})
#define ADD_QUEUE( q, d )   ({ q->a[(q->h + q->s++) % q->c] = d; })
#define POLL_QUEUE( q, d )  ({ *d = q->a[q->h]; q->h = (q->h + 1) % q->c; --q->s; })
#define PEEK_QUEUE( q, d )  ({ *d = q->a[q->h]; })
#define SIZE_QUEUE( q )     (q->s)
#define EMPTY_QUEUE( q )    (q->s < 1)
#define FULL_QUEUE( q )     (q->s >= q->c)
#define CLEAR_QUEUE( q )    ({ q->h = q->s = 0; })
#define DEL_QUEUE( q )      ({ if( q != NULL && *q != NULL ) { free( *q ); *q = NULL; } })

typedef struct Queue {
int32_t c;
int32_t s;
int32_t h;
void *a[0];
} Queue;

void levelOrderTraversal( NodeBinaryTree *root ) {
Queue *q = NULL;

NEW_QUEUE( &q, 10000 );
if( root != NULL ) {
}
while( !EMPTY_QUEUE( q ) ) {
int32_t count = SIZE_QUEUE( q );
while( --count >= 0 ) {
POLL_QUEUE( q, &root );
printf( "%d, ", root->val );
if( root->left != NULL ) {
}
if( root->right != NULL ) {