Data Structure: The traverse and storage of Binary Tree
1 Chain Storage of Binary Tree
Usually, we use link list to store a binary tree, the structure could be seen as follow:
We can see that the node is constructed with three parts: the pointer to the left child and right child, as well as the data field.
Code Implementation:
/* Chain storage of binary tree */
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode{
int data; // Data field
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree *T){
*T=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->data=1;
(*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->data=2;
(*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->data=3;
(*T)->rchild->lchild=NULL;
(*T)->rchild->rchild=NULL;
(*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->lchild->data=4;
(*T)->lchild->rchild=NULL;
(*T)->lchild->lchild->lchild=NULL;
(*T)->lchild->lchild->rchild=NULL;
}
int main() {
BiTree Tree;
CreateBiTree(&Tree);
printf("%d\n",Tree->data);
printf("%d\n",Tree->lchild->data);
printf("%d\n",Tree->rchild->data);
printf("%d",Tree->lchild->lchild->data);
return 0;
}
Output:
2 Traverse of binary tree
2.1 Recursive Implementation
#include <stdio.h>
#include <stdlib.h>
#define TElemType int
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
// Initialize
void CreateBiTree(BiTree *T){
*T=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->data=1;
(*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->data=2;
(*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild->data=5;
(*T)->lchild->rchild->lchild=NULL;
(*T)->lchild->rchild->rchild=NULL;
(*T)->rchild->data=3;
(*T)->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->lchild->data=6;
(*T)->rchild->lchild->lchild=NULL;
(*T)->rchild->lchild->rchild=NULL;
(*T)->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->rchild->data=7;
(*T)->rchild->rchild->lchild=NULL;
(*T)->rchild->rchild->rchild=NULL;
(*T)->lchild->lchild->data=4;
(*T)->lchild->lchild->lchild=NULL;
(*T)->lchild->lchild->rchild=NULL;
}
void displayElem(BiTNode* elem){
printf("%d ",elem->data);
}
// Preorder traversal
void PreOrderTraverse(BiTree T){
if (T) {
displayElem(T); // Visit the node
PreOrderTraverse(T->lchild); // Visit the leftchild
PreOrderTraverse(T->rchild); // Visit the rightchild
}
// If the node is empty, back to the layer above
return;
}
// Inorder traversal
void INOrderTraverse(BiTree T){
if (T) {
INOrderTraverse(T->lchild);
displayElem(T);
INOrderTraverse(T->rchild);
}
return;
}
// Postorder traversal
void PostOrderTraverse(BiTree T){
if (T) {
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
displayElem(T);
}
return;
}
int main() {
BiTree Tree;
CreateBiTree(&Tree);
printf("Preorder traversal: \n");
PreOrderTraverse(Tree);
printf("\nInorder traversal: \n");
INOrderTraverse(Tree);
printf("\nPostorder traversal: \n");
PostOrderTraverse(Tree);
}
Output:
2.2 Level Reversal
Here we introduce another traversal method, by using the data structure: queue, we can traverse the binary tree easily:
The main idea of the algorithm is that it put the parent node into the queue first, when the parent node get out of the queue, its left child and right child will enter the queue.
/* Level reversal */
#include <stdio.h>
#include <stdlib.h>
int front=0,rear=0;
typedef struct BiTNode{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree *T){
*T=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->data=1;
(*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->data=2;
(*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild->data=5;
(*T)->lchild->rchild->lchild=NULL;
(*T)->lchild->rchild->rchild=NULL;
(*T)->rchild->data=3;
(*T)->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->lchild->data=6;
(*T)->rchild->lchild->lchild=NULL;
(*T)->rchild->lchild->rchild=NULL;
(*T)->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->rchild->data=7;
(*T)->rchild->rchild->lchild=NULL;
(*T)->rchild->rchild->rchild=NULL;
(*T)->lchild->lchild->data=4;
(*T)->lchild->lchild->lchild=NULL;
(*T)->lchild->lchild->rchild=NULL;
}
void EnQueue(BiTree *a,BiTree node){
a[rear++]=node;
}
BiTNode* DeQueue(BiTNode** a){
return a[front++];
}
void displayNode(BiTree node){
printf("%d ",node->data);
}
int main(){
BiTree tree;
CreateBiTree(&tree); // Initialize the binary tree
BiTNode *p;
BiTree a[20]; // Array of sequential queue
EnQueue(a,tree); // The parent node enter the queue
while(front<rear){ // Stop when front=rear(means the queue is empty)
p=DeQueue(a);
displayNode(p);
if (p->lchild!=NULL) {
EnQueue(a, p->lchild);
}
if (p->rchild!=NULL) {
EnQueue(a, p->rchild);
}
}
return 0;
}
Output: