All children to the left of a particular node have lower values, and all children to the right have higher values .
The multiple pointers at each node reduce the time complexity of operations by reducing the number of nodes one must visit to find an item,
We can implement binary tree using:
1. dynamically created node:
typedef struct Nameval Nameval1;
struct Nameval{
char *name;
int value;
Nameval *left; //lesser
Nameval *right; //greater
};
2.arrays
BST
Binary Tree:
1.height of node : length of longest path from it down to a leaf.
2.max number of nodes in a tree with height of h equals : 2h+1-1
3.Height of perfect binary tree with n nodes = log 2 (n +1)-1
4.for node at index i:
left child index=2i+1;
right child index = 2i +2;
BST Property
Let x be a node in a BST, if y is a node in the left subtree of x, then key [y ]≤key [x ].If y is a node in the right subtree of x, then key [x ]≤key [y ].
Theorem 12.1.
If x is the root of an n -node subtree, then the call INORDER -TREE -WALK (x ) takes Θ(n )time.
Max & Min
Pseudocode of maximum:
TREE-MINIMUN
while left[x] ≠NIL
do x ←left [x]
return x
the Maximum is symmetric
Successor & predecessor
If all keys are distinct, the successor of a node x is the node with the smallest key greater than key[x].
Tree -Successor (x)
if right [x ]≠NIL
then return Tree -minimum (right [x ])
y ←p[x]
while y ≠NIL and x=right[y]
do x ←y
y ←p[x]
return y
Insert
/*insert:insert newp in the treep,return treep*/
Nameval *insert(Nameval *treep,Nameval *newp)
{
int cmp;
if(treep==Null)
return newp;
cmp=strcmp(newp->name,treep->name);
if(cmp==0)
weprintf("insert; duplicate entry %s ignores",newp->name);
else if(cmp<0)
treep->left=insert(treep->left,newp);
else if
treep->right=insert(treep->right,newp);
return treep;
}
In the first scenario,we ignore duplicate entries.
struct tree* insert(struct tree *treep,int n)
{
if(treep==NULL)
{
return New(n);
}
if(n<= treep->data)
{
treep->left=insert(treep->left,n);
}
else
{
treep->right=insert(treep->right,n);
}
return treep;
}
A tree in which each path from the root to a leaf has approximately the same length is called balanced.Searching it for an item is an O(logn) process.
View complete code of Insert element in BST here.
Search
//lookup:look up name in tree treep
Nameval *lookup(Nameval *treep,cgar *name)
{
int cmp;
if(treep == NULL)
return NULL;
cmp=strcmp(name,treep->name);
if(cmp == 0)
return treep;
else if (cmp<0)
return lookup(treep->left,name);
else
return lookup(treep->right,name);
}
These routines are recursive,lookup's last action is return the result of a call to itself, a situation called tail recursion.This can be converted to iteration by patching up the arguments and restarting the routine.The most direct method is to use a goto statement,but a while loop is cleaner:
//nrlookup:non-recursively lookup name in tree treep
Nameval *nrlookup(Nameval *treep, char *name)
{
int cmp;
while(treep!=NULL)
{
cmp=strcmp(name,treep->name);
if(cmp==0)
return treep;
else if (cmp<0)
treep=treep->left;
else
treep=treep->right;
}
return NULL;
}
my code:
struct tree *search(struct tree* Root,int key)
{
if(Root == NULL)
{
printf("Not found\n");
return NULL;
}
if(key < Root->data)
{
return search(Root->left,key);
}
else if(key > Root->data)
{
return search(Root->right,key);
}
else
{
printf("key found\n");
return Root;
}
}
View complete code of Search here
Pre-order traversal
1.Check if the current node is empty / null
2.Display the data part of the root (or current node).
3.Traverse the left subtree by recursively calling the pre-order function.
4.Traverse the right subtree by recursively calling the pre-order function.
void preorder(struct tree *p)
{
if (p != NULL)
{
printf("%d \n", p->data);
preorder(p->left);
preorder(p->right);
}
}
In-order traversal
An in-order traversal executes the operation after visiting the left subtree and before visiting the right subtree:
//applyinoder:in-order application of fn to treep
void applyinorder(Nameval *treep,void(*fn)(Nameval*,void*)void *arg)
{
if(tree == NULL)
return;
applyinorder(treep->left,fn,arg);
(*fn)(treep,arg);
applyinorder(treep->right,fn,arg);
}
void inorder(struct tree *p)
{
if (p != NULL)
{
inorder(p->left);
printf("%d \n", p->data);
inorder(p->right);
}
}
Post-order
Post-order traversal is used when the operation on the node depends on the subtrees below it.Examples: computing the height of a tree,laying out a tree in a graphics drawing package ,and measuring total storage.
void postorder(struct tree *p)
{
if (p != NULL)
{
postorder(p->left);
postorder(p->right);
printf("%d \n", p->data);
}
}