GKM COLLEGE OF ENGINEERING & TECHNOLOGYDATA STRUCTURES (CS2201 /141301) Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 Tree ADT A tree can be defined in several ways. One natural way to define a tree is recursively. A tree is a collection of nodes. The collection can be empty, which is sometimes denoted as A. Otherwise, a tree consists of a distinguished node r, called the root, and zero or more (sub)trees T1, T2, . . . , Tk, each of whose roots are connected by a directed edge to r. he root of each subtree is said to be a child of r, and r is the parent of each subtree root. Figure 4.1 shows a typical tree using the recursive definition. From the recursive definition, we find that a tree is a collection of n nodes, one of which is the root, and n - 1 edges. That there are n - 1 edges follows from the fact that each edge connects some node to its parent and every node except the root has one parent. Basic structure of a tree: Issue : C Rev:01 Page:2of 2 Period:1 Figure: A tree t t h / : p s c / u t e . e b / k t n the tree of Figure the root is K, L, and M as children. Each node may children, possibly zero. Nodes with no the leaves in the tree above are B, C, A. Node F has A as a parent and have an arbitrary number of children are known as leaves; H, I, P, Q, K, L, M, and N. http://csetube.weebly.com/ The height of a tree is equal to the height of the root. the height of the tree is 3. nk such that ni is the parent of ni+1 for 1 i < k. the root is at depth 0. For any node ni. For the tree in Figure 4. L. path from node n1 to nk is defined as a sequence of nodes n1. The length of this path is the number of edges on the path. . .weebly. namely k -1.com/ . the depth of ni is the length of the unique path from the root to ni.Nodes with the same parent are siblings. E is at depth 1 and height 2. e b / k t http://csetube. Thus all leaves are at height 0. The height of ni is the longest path from ni to a leaf. thus K. F is at depth 1 and height 1.2. then n1 is a proper ancestor of n2 and n2 is a proper descendant of n1. t t h / : p s c / u t e . If n1 &n2. then n1 is an ancestor of n2 and n2 is a descendant of n1. If there is a path from n1 to n2. this is always equal to the height of the tree. and M are all siblings. . There is a path of length zero from every node to itself. . Thus. n2. The depth of a tree is equal to the depth of the deepest leaf. Grandparent and grandchild relations can be defined in a similar manner. Notice that in a tree there is exactly one path from the root to each node. com/ .weebly. Tree traversal is a method for visiting all the nodes in the tree exactly once. -traverse the right subtree in preorder. Inorder(T->right).there are 3 types of tree traversal techniques. t t h / : p s c / u t e . Void Inorder(Tree T) { If(T!=NULL) { InOrder(T->Left). e b / k t -traverse the left subtree in preorder. } } 2. printElement(T->Element).namely 1.Inorder Traversal -traverse the left subtree inorder -visit the root -traverse the right subtree in inorder. Void Preorder(Tree T) { http://csetube.Preorder traversal -visit the root.Lecture Plan Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 Issue : C Rev:01 Page:2of 2 Period:2 Tree Traversals with an Application Traversing means visiting each node only once. } } 3.postorder traversal -traverse the left subtree in postorder. -traverse the right subtree in postorder. Void Postorder(Tree T) { If(T!=NULL) { Postorder(T->Left).com/ .weebly.If(T!=NULL) { printElement(T->Element). -visit the root. e b / k t http://csetube. Preorder(T->Left). } } t t h / : p s c / u t e . Preorder(T->Right). Postorder(T->Right). printElement(T->Element). it might be infeasible to make the children direct links in the data structure. However. The declaration in Figure is typical. tree_ptr next_sibling. struct tree_node { element_type element.Lecture Plan Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 Issue : C Rev:01 Page:2of 2 Period:3 Implementation of Trees One way to implement a tree would be to have in each node. e b / k t http://csetube. typedef struct tree_node *tree_ptr.com/ . tree_ptr first_child. a pointer to each child of the node. The solution is simple: Keep the children of each node in a linked list of tree nodes. }. besides its data. because there would be too much wasted space. since the number of children per node can vary so greatly and is not known in advance. t t h / : p s c / u t e .weebly. Figure shows that a binary tree consists of a root and two subtrees. the example in Figure shows. e b / k t Figure :Worst-case binary tree Binary tree node declarations: typedef struct tree_node *tree_ptr. struct tree_node { element_type element. tree_ptr right. http://csetube. }. Tl and Tr.com/ . both of which could possibly be empty. Figure :Generic binary tree t t h / : p s c / u t e .Lecture Plan Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 Issue : C Rev:01 Page:2of 2 Period:4 Binary Trees A binary tree is a tree in which no node can have more than two children. A property of a binary tree that is sometimes important is that the depth of an average binary tree is considerably smaller than n. typedef tree_ptr TREE.weebly. tree_ptr left. com/ . One of the principal uses of binary trees is in the area of compiler design. because every binary tree with n nodes would require n + 1 NULL pointers.Many of the rules that apply to linked lists will apply to trees as well. Binary trees have many important uses not associated with searching. Nodes can be freed after deletion by calling free. In particular. because they are actually graphs. e b / k t http://csetube. a node will have to be created by a call to malloc. We also do not explicitly draw NULL pointers when referring to trees. when an insertion is performed. which we will now explore. t t h / : p s c / u t e . but trees are generally drawn as circles connected by lines.weebly. We could draw the binary trees using the rectangular boxes that are customary for linked lists. Example: (a + (b*c)) + (((d * e) + f)* g). and although this is the simplest case. as is the case with the unary minus operator.* *For convenience. by applying the operator at the root to the values obtained by recursively evaluating the left and right subtrees.Lecture Plan Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 Issue : C Rev:01 Page:2of 2 Period:5 Expression Trees The leaves of an expression tree are operands. Constructing an Expression Tree As an example. such as constants or variable names. This particular tree happens to be binary.weebly. We can evaluate an expression tree.com/ . suppose the input is a b + c d e + * * t t h / : p s c / u t e . It is also possible for a node to have only one child. e b / k t The first two symbols are operands. and the other nodes contain operators. so we create one-node trees and push pointers to them onto a stack. because all of the operations are binary. we will have the stack grow from left to right in the diagrams. T. it is possible for nodes to have more than two children. http://csetube. Next. a '*' is read.com/ . a '+' is read. and for each a one-node tree is created and a pointer to the corresponding tree is pushed onto the stack. Continuing. c.* Next. and a pointer to it is pushed onto the stack. h p t t :/ s c / u t e . and e are read. e b / k t http://csetube. Now a '+' is read.weebly. d. so two trees are merged. a new tree is formed. so we pop two tree pointers and form a new tree with a '*' as root. so two pointers to trees are popped. t t h / : p s c / u t e . struct tree_node http://csetube. X.com/ . e b / k t Issue : C Rev:01 Page:2of 2 Period:6 Figure:Two binary trees (only the left tree is a search tree) Binary search tree declarations typedef struct tree_node *tree_ptr. in the tree.weebly. two trees are merged. Lecture Plan Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 Binary Search Trees: The property that makes a binary tree into a binary search tree is that for every node. and the values of all the keys in the right subtree are larger than the key value in X. the last symbol is read. and a pointer to the final tree is left on the stack.Finally. the values of all the keys in the left subtree are smaller than the key value in X. SEARCH_TREE T ) http://csetube. if( x < T->element ) return( find( x. else return( find_min ( T->left ) ). } t t h / : p s c / u t e . }. tree_ptr right. Some programmers prefer to initialize the first element as a one-node tree. e b / k t Insert tree_ptr insert( element_type x. Make_null This operation is mainly for initialization.com/ . SEARCH_TREE make_null ( void ) { return NULL. else return T.{ element_type element.weebly. else if( T->left == NULL ) return( T ).} Find_min and find_max tree_ptr find_min( SEARCH_TREE T ) { if( T == NULL ) return NULL. but our implementation follows the recursive definition of trees more closely. SEARCH_TREE T ) { if( T == NULL ) return NULL. } Find tree_ptr find( element_type x. T->right ) ). typedef tree_ptr SEARCH_TREE. else if( x > T->element ) return( find( x. T->left ) ). tree_ptr left. h p t t s c Lecture Plan / :/ u t e . SEARCH_TREE T ) {tree_ptr tmp_cell. } } else if( x < T->element ) T->left = insert( x.{ if( T == NULL ) { T = (SEARCH_TREE) malloc ( sizeof (struct tree_node) ). else { T->element = x.weebly. } Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 Binary Search Trees Delete tree_ptr delete( element_type x. T->left ). else if( x > T->element ) /* Go right */ T->right = delete( x. T->left ). e b / k t Issue : C Rev:01 Page:2of 2 Period:7 http://csetube. return T.com/ . T->left = T->right = NULL. else if( x < T->element ) /* Go left */ T->left = delete( x. T->right ). T->right ). if( T == NULL ) fatal_error("Out of space!!!"). child. if( T == NULL ) error("Element not found"). else if( x > T->element ) T->right = insert( x. T->right = delete( T->element. e b / k t Issue : C Rev:01 Page:2of 2 Period:8 Applications of trees: Trees are often used in and of themselves to store data directly. T->right ). Sets and Maps and other associative containers. particularly “board” games http://csetube. free( tmp_cell ). if( T->right == NULL ) /* Only a left child */ child = T->left. } else /* One child */ } tmp_cell = T.else /* Found element to be deleted */ if( T->left && T->right ) /* Two children */ { /* Replace with smallest in right subtree */ tmp_cell = find_min( T->right ). } return T. the C++ Standard Template Library uses special red/black trees as the underlying implementation for sets and maps. } Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 t t h /Lecture Plan : p s c / u t e .weebly. return child. T->element = tmp_cell->element. Specifically. however they are also often used as the underlying implementation for other types of data structures such as Hash Tables. as well as multisets and multimaps. if( T->left == NULL ) /* Only a right child */ child = T->right.com/ . Trees and Board Games – Trees are often used in implementinggames. .node represents a position in the board . http://csetube.com/ ."[1] A threaded binary tree makes it possible to traverse the values in the binary tree via a linear traversal that is more rapid than a recursive in-order traversal.branches from a node represent all thepossible moves from that position -the children represent the new positions Planning a Move Ahead – equivalent to choosing a path through the game tree Games with Cycles – it is possible to return to a previous position Code:141301 Name of the subject :Data Structures &Algorithms Unit No:2 t t h / : p Lecture Plan Issue : C Rev:01 Page:2of 2 Period:9 s c / u t e . e b / k t Threaded binary tree : "A binary tree is threaded by making all right child pointers that would normally be null point to the inorder successor of the node. and all left child pointers that would normally be null point to the inorder predecessor of the node.weebly. It is also possible to discover the parent of a node from a threaded binary tree.com/ . To see how this is possible.weebly. consider a node k that has a right child r. that left child must in turn have either a left child of its own or a thread back to k. Then the left pointer of r must be either a child or a thread back to k. In the case that r has a left child. So by following the chain of left pointers from r. A threaded tree. we will eventually find a thread pointing back to k. albeit slowly. e b / k t http://csetube. with the special threading links shown by dashed arrows t t h / : p s c / u t e . The situation is symmetrically similar when q is the left child of p—we can follow q's right children to a thread pointing ahead to p. without explicit use of parent pointers or a stack. or where a stack of parent pointers is unavailable (for finding the parent pointer via DFS). This can be useful where stack space is limited. and so on for all successive left children.