You are on page 1of 49

TREES

Trees
Tree is a non linear data structure & is mainly used to represent data containing a hierarchical relationship between elements.

Binary Tree
Binary Tree is defined as a finite set of elements called nodes, such that
T is empty (called the null tree or empty tree) T contains a distinguished node R (root) and the remaining nodes of T form an ordered pair of disjoint binary trees T1 & T2.

Any node N in a binary tree has either 0,1, or 2 successors.

Edge a line drawn from a node N of T to a successor is called an edge. Path a sequence of consecutive edges.

Each node in a binary tree T is assigned a level no. The root R of a tree T is assigned the level no 0. Same level nodes are said to belong to the same generation

Depth (Height) of a tree T is the maximum number of nodes in a branch of T. This turns out to be one more than the largest level number of T. Tree with only one node (the root) has a height of one.

Trees Terminology
Root no parent Leaf no child Interior non-leaf Height maximum number of nodes in a branch of T
Root node

Interior nodes
Leaf nodes

size 9 and height 4,

Binary Tree Memory Representaion


Array Representation:
1. Father of node n is floor((n-1)/2) if n!=0, if n=0 then it is the root node. 2. LeftChild(n) = 2*n+1 3. RightChild(n)=2*n+2 4. Siblings:
1. Right sibling of node at index n is = n+1 2. Left sibling of node at index n is = n-1

Array Representation is mostly suitable for complete binary tree, but for other, there are wastage of memory.

Linked List representation:

Complete Binary Trees


Any binary tree is said to be complete if all its levels, except possibly the last, have the maximum number of possible nodes. The left and right children of the node k are 2*k +1 and 2*k+2 and the parent of node k is floor((k-1)/2). The depth of the complete binary tree Tn with n nodes is Dn = floor(log2n+1)

Strictly Binary Tree


Every non-terminal node in a binary tree consists of non empty left subtree and right subtree. A binary tree is proper (strictly binary tree) if each internal node has two children. Example: Any algebraic expression which uses only binary operations

Arithmetic Expression Tree


Binary tree associated with an arithmetic expression
internal nodes: operators external nodes: operands

Example: arithmetic expression tree for the expression (2 (a - 1) + (3 b)) +

2
a

Extended Binary Tree: 2-Trees


A binary tree T is said to be a 2-tree or an extended binary tree if each node N has either 0 or 2 children. .

Traversing a Binary Tree


3 standard ways of traversing a binary tree T: Preorder:
1. Process the root N 2. Traverse the left subtree of N in Preorder 3. Traverse the right subtree of N in Preorder

NLR

Preorder (NLR) Traversal


For the expression (2 (a - 1) + (3 b))

2
a

Preorder (NLR)Traversal of the tree: +2a13b

Inorder:
1. Traverse the left subtree of N in Inorder. 2. Process the root N. 3. Traverse the right subtree of N in Inorder.

LNR

Inorder (LNR) Traversal


For the expression (2 (a - 1) + (3 b))

2
a

Inorder (LNR)Traversal of the tree: 2a1+3b

Postorder:
1. Traverse the left subtree of N in Postorder. 2. Traverse the right subtree of N in Postorder 3. Process the root N

LRN

Postorder (LRN) Traversal


For the expression (2 (a - 1) + (3 b))

2
a

Postorder (LRN)Traversal of the tree: 2, a, 1, , , 3, b, , +

Binary Search Tree(BST)


Let us assume T is a binary search tree. Then T is a binary search tree, if each node N of T has the following property: The value at N is greater than every value in the left subtree of N and is less than every value in the right subtree of N

Binary Search Trees


Key property
Value at node
Smaller values in left subtree Larger values in right subtree

Example
X>Y X<Z

Binary Search Trees


Examples
5

10
2 5 2 25 30 45 5

10 45

30
45 10

2 25

25

30

Binary search trees

Not a binary search tree

Inserting and Searching in a BST


Suppose T is a BST and an ITEM of information is given to be inserted into the tree. Compare ITEM with the root node N of BST. (a)(i) If ITEM< N, proceed to the left child of N. (ii)If ITEM>N, proceed to the right child of N.

(b) Repeat step (a) until one of the following occurs (I) A node such that ITEM = N (successful search) (II) An empty subtree is found, indicating unsuccessful search. Then we insert ITEM in place of empty subtree.

Program
Struct Node{ int info; Node* left; Node* right; }

Insert
Node* Insert(Node* tree, int item) { if(tree==NULL){ tree =(Node*) malloc(sizeof(Node)); tree->left = tree->right = NULL; tree->info = item; }

Insert
else if(item < tree->info) tree->left= Insert(tree->left, item);

else if(item > tree->info) tree->right = Insert(tree->right, item);

Insert
else { printf(Duplicate Node\n); exit;}

return(tree); }

Search
Void Search(Node* tree, int item) { if(tree==NULL) printf(Tree is empty\n); else if(item == tree->info) printf(The item is %d \n, item);

Search
else if ( item < tree->info) Search(tree->left, item);

else Search(tree->right, item);


}

Preorder
void Preorder(NodeT* tree) { if(tree!=NULL){ printf(%d\n,tree->info); Preorder(tree->left); Preorder(tree->right); }

Inorder
void Inorder(NodeT* tree) { if(tree!= NULL){ Inorder(tree->left); printf(%d\n, tree->info); Inorder(tree->right); }

Postorder
void Postorder(NodeT* tree){ if(tree!=NULL) { Postorder(tree->left); Postorder(tree->right); printf(%d\n,tree->info); } }

To find out the level of a node


int getLevel(NodeT* tree, int data) { if(tree != NULL) { static int l=0; if(data == tree->info) return l; else if(data<tree->info) { l++; getLevel(tree->left, data); } else if(data>tree->info) { l++; getLevel(tree->right,data); } } else { printf("Key not found\n"); return(-1); } }

To find out the parent of a node


NodeT* findParent(NodeT* tree, NodeT* ptr) { NodeT *p; if(tree == NULL) return tree; else { else if(tree->left == ptr || tree->right == ptr ) return tree; else { if(ptr->info < tree->info) p = findParent(tree->left, ptr); else p = findParent(tree->right, ptr); return p; }

Deletion
There are three possible cases to consider: Deleting a leaf (node with no children): Deleting a leaf is easy, as we can simply remove it from the tree. Deleting a node with one child: Remove the node and replace it with its child.

Deletion
Deleting a node with two children: Call the node to be deleted N. Do not delete N. Instead, choose either its in-order successor node or its in-order predecessor node, R. Replace the value of N with the value of R, then delete R.

Deletion
As with all binary trees, a node's in-order successor is the left-most child of its right subtree, and a node's in-order predecessor is the right-most child of its left subtree. In either case, this node will have zero or one children. Delete it according to one of the two simpler cases above.

Deletion

Search function which returns the address of the node


tree* searchAddress(NodeT* tree, int item, int * flag) { if(tree==NULL) { *flag = 0; printf(Tree is empty\n); return tree; } else if(item == tree->info) { *flag = 1; printf(The item is %d \n, item); return tree; } else if ( item < tree->info) return searchAddress (tree->left, item, flag); else return searchAddress (tree->right, item, flag); }

Function to find the parent of a given node


NodeT* findParent(NodeT* tree, NodeT* ptr) { NodeT *p; if(tree == NULL) return tree; else { if(tree->left == ptr || tree->right == ptr ) return tree; else { if(ptr->info < tree->info) p = findParent(tree->left, ptr); else p = findParent(tree->right, ptr); return p; } } }

Function to find the inorder successor of a given node


// Function to find inorder successor

NodeT* findSuc(NodeT * tree, NodeT* p) { if(tree == NULL) { printf("Empty tree\n"); return tree; } else { NodeT* sucPtr = p->right; while(sucPtr->left != NULL) sucPtr = sucPtr->left; return sucPtr; } }

Delete function (Case A slide 1)


NodeT* delNodeCaseA(NodeT* tree, NodeT* ptr, int *flag) { NodeT* parent = findParent(tree, ptr); if(ptr->left==NULL && ptr->right == NULL) //leaf node { if(parent->left == ptr) parent->left = NULL; else parent->right = NULL; free(ptr); return tree; }

Delete function (Case A slide 2)


if(ptr->left !=NULL && ptr->right ==NULL) //Node contains one left child { if(parent->left ==ptr) parent->left = ptr->left; else parent->right = ptr->left; free(ptr); return tree; } if (ptr->left ==NULL && ptr->right !=NULL) //Node contains one right child { if(parent->left ==ptr) parent->left = ptr->right; else parent->right = ptr->right; free(ptr); return tree; } }

Delete function (main function, which is calling Case A ) slide 1


NodeT* delNode(NodeT* tree, int item, int * flag) { NodeT * ptr, *parent, *sucPtr; if(tree==NULL) { *flag = 0; printf("Tree is empty\n"); ptr = searchAddress(tree, item, flag); if(*flag == 1) parent = findParent(tree, ptr); else return tree; if(ptr->left == NULL || ptr->right == NULL) tree = delNodeCaseA(tree, ptr, flag); else

return tree;

Delete function (main function, which is calling Case A ) slide 2


//Node containing two children { sucPtr = findSuc(tree, ptr); ptr->info = sucPtr->info; tree = delNodeCaseA(tree, sucPtr, flag); } return tree; }