 Hello and welcome to another session on trees in which we will look at some other examples of trees. So, in general there are many kinds of tree structures depending on different applications. So, there are many special kinds of trees used for specific purposes. So, we will look at again one example of some general type of tree. The common property in all these structures is that there is a starting node called a root node and a node can have 0 or more next nodes which are called as children. But a node cannot be a child of more than one node. So, if a node has essentially unique parent and all nodes can be re-starting from the root node. So, that is start with the root node, look at its children, then look at its grandchildren and so on. This will give you all the nodes in the tree structure and many kinds of tree structures can be built with this property. So, look at one general class of trees called rooted trees. So, this is similar to a binary tree, we again have a single operation called plant n, s where n is a node. But now instead of just having two earlier trees left and r, l and r, we have a sequence of rooted trees s. So, rooted tree is obtained by taking a node n and any sequence of rooted trees s. So, remember we have already defined what a sequence of any type is. So, if you have rooted trees is also a type, we can take a sequence of that type and plant it with node n to get another rooted tree. So, unlike a binary tree, a rooted tree is never empty, it will always have the root node together with a sequence of rooted trees. But that sequence itself may possibly be empty. So, the sequences of rooted trees can contain any number of trees possibly 0, whereas in a binary tree it always contains two binary trees, one of which we call the left and the other is the right. So, the simplest rooted tree is plant n, 5 where 5 is the empty sequence of rooted trees. So, many terms that are used for binary trees also apply to rooted trees. So, if you have a tree which is plant n s, the node n is called the root of the tree. The trees in the sequences are also called a rooted tree, they are called the subtrees of t and also of the node n. Now, in this case a node can have any number of subtrees because s is a sequence, it can contain any number of elements and element of the sequences is a rooted tree. So, there can be any number of subtrees for a node. And if a node n is the root of the ith tree in the sequences, then m is called the ith child of m and n is the parent of m. So, unlike a left child and a right child in a binary tree, they have a 0 at child, the first child, second child and so on for a node in a rooted tree and in general it can have any number of children starting from 0. So, similarly in binary trees, the node n and all the nodes in the subtrees, that is, all the trees in s are said to be contained in the tree tree. So, how will you define height of and size? Just like as in the case of binary trees, height of a tree obtained by planting n with an empty sequence of subtrees is 0 and otherwise height of plant n, push t, s. So, now remember we have the second element is not a tree, but it is a sequence of trees. So, in the first case, if the sequence is empty, then the height is defined to be 0. Otherwise, the sequence contains some tree t which has been pushed into a sequence s. Then we look at the height of t, t is a rooted tree. We find 1 plus the height of the tree and take height of the tree obtained by planting n with the remaining sequence of subtrees. So, we take the first sub tree t, its height, take 1 plus that and compare it with the height of the tree obtained by planting the remaining sequence at node n and the maximum of these two gives the height of the tree. The same holds for the size, we just add the size of the tree t to the size of the remaining sub sequence s and that gives the size of the tree t. Pre-order and post-order traversals can be defined for trees, but not in-order traversals. So, in-order traversals was defined for binary trees where we first traverse the left subtrees, then the root and then the right subtrees. So, this was possible because there were only two subtrees left and right, but here when you have any number of subtrees, we do not know where to place the root. So, there are only two orders, pre-order in which we place the root first, that is we push the root first, then pre-order of all the subtrees and post-order is the other way, we push the root at the end of the post-orders of all the subtrees. So, to define this, you need to define a new operation here called sub-tree pre-order which takes a sequence of trees and visits each of the subtrees in pre-order and concatenates the pre-order traversal. So, sub-tree pre-order for a sequence of trees is defined by take the pre-order of the first sub-tree and then sub-tree pre-order of the remaining sequence and concatenate them. Whereas, for post-order, we get a simpler definition which is post-order of the empty sequence is just obtained by pushing the root node in that and if we push a tree T in the sequence S, then we first traverse T in post-order and then take post-order of the remaining sequence planted at root N. So, there is a more compact definition than pre-order for root general root at tree. So, actually binary trees and root at trees are quite similar and we can represent root at trees by binary trees. So, this is a function which converts a root at tree into a binary tree which has one less number of nodes than the root at tree. So, if a root at tree has a node N and an empty sequence of sub-trees, it is represented by the empty binary tree. On the other end, binary tree which is obtained by taking a root node of a root at tree obtained with a root node N and a sequence push T comma S, it is obtained by planting at the root of T, the binary tree of the left sub-trees and the binary tree obtained by planting the sequence S at node N. So, you can check that this gives us a valid definition of a binary tree which converts a rooted tree into a binary tree. So, here root of a rooted tree is just a function that returns the root node of the tree. So, root of plant of N is returns the node N which we use for rooting the binary tree that is constructed. And similarly you can define an inverse function for this which takes a binary tree and converts it into a corresponding rooted tree which will have one more node than the number of nodes in the binary tree. So, we look at one example of an application of rooted trees which is called tribes and this is essentially used to represent a set of character strings. So, let us say we want to represent telephone numbers, mobile phone numbers. So, each number is a sequence of 10 decimal digits. So, we have a large collection of phone numbers which we want to represent them. So, we can use rooted trees to represent them in a more compact way compared to even binary search trees. So, here the root node will represent the entire set of numbers. So, we have a collection of set of numbers. The root node number represents the entire set and each node in this rooted tree will store a true false value to indicate whether the empty set belongs to the set represented by the sub tree having that node as root. So, every node is the root of some sub tree and we store a true false value to indicate whether the empty set belongs to that. So, what we do is we have this initial set of sequences. We partition them into disjoint subset based on the first digit of the sequence. So, we leave out empty sequence. If a sequence begins with digit 0, we put it in set S0. If it begins with digit 1, we put in S1 and so on. So, we get disjoint subsets of sequences. And now, the ith sub tree of the root node will represent the set of sequences that is obtained from Si by deleting the first digit. So, we take all sequences starting with 0, remove the first digit 0 from that. Whatever are the remaining sequences, that set is represented by the 0th sub tree of the root node. So, each node will either have no sub trees at all or if the set does not contain any non-empty sequence, then it will have not have any sub tree at all or it will have 10 sub trees corresponding to each possible value for the first digit. And if it is 0, then it can either represent the empty set or the set containing the empty sequence. So, how would find operation work? So, if you want to find the empty sequence in a tree obtained by planting a sequence of trees at root n, then we just look at the value of n. If the value of n is true, then it means the empty sequence belongs to the set. If the value of n is false, then we say it does not belong. Otherwise, if a sequence is obtained by pushing the digit d into a sequence s and if our tree has no sequence of sub trees, then of course, there is no sequence contained in that sub tree in the set represented by that. So, we return false. Otherwise, if we have sub trees for the root node of that and our sequence begins with the digit d, we find the d-th sub tree of the root node. So, remember t is a sequence of sub trees. The element at t, d gives the d-th sub tree in the sequence t. The d is the first digit of the sequence s. And now in that sub tree, we search for the element s, the sequence s, the remaining sequences. So, this will give us a fine function on a try. And similarly, we can write insert and delete functions for this. So, you should try writing these as exercises. And now, how does this compare with a binary search tree? So, you can see that the time required for this, if you are dealing with 10 digits cell telephone numbers, then the height of the tree is at most 10. Height of the rooted tree, we just go through 10 digits at each step. Every time, we go to an appropriate sub tree, one of the 10 possible sub trees. So, the time here is independent of how many telephone numbers that you have in the set. It does not depend on how many elements are there in the set. It only depends on the length of the sequence, which is 10 in this case. So, this is a more efficient way of representing sets of sequences, but it is not useful for sets of arbitrary type. So, there we need to use binary search trees. In the next session, we will look at more general structures which are not sequential and which are used for many other applications also. Thank you.