 Hello and welcome to this session in which we will look at yet another data structure whose value is a sequence and this can be called as lists or arrays sometimes also. They differ from stacks or queues in the sense that we are more powerful and there are many more operations defined on these objects. The stack and queues had some few simple operations like push and pop or insert defined for them. Lists have many more general operations defined already defined which can be used more easily and elements in a list can be accessed by their position in the list. So position is also another type whose value you can think of are just numbers or sometimes we also call it as an index in an array. So list operations use positions in the list as parameters and we will see that we can define many more operations on lists compared to stacks or queues. So list position is another type whose value you can think of it as just a number. So 0 is a position and if p is a position then there is a next position called next of p. Sometimes we also need a previous operation defined on numbers or position. Previous of 0 is undefined whereas previous of next of p is equal to p. So given any position p we can define a previous position to that except for the 0th position where it is undefined. And usually we need only these two operations for position. Given a current position we can move to the next or the previous position. And list operations will usually use positions as a parameter for the operation. So here is an example of an operation which finds the element in the list l at position p. So we call this operation as element at l is a list and p is a position and this returns an element in the list l which occurs at position p. So if the list is empty then there is no element at any position. So element at 5 of p is undefined for all positions p. If the list is non-empty that is obtained by pushing an element x in some list l then the element at position 0 is just the element x itself. So if the value of the list is push x, l the element at position 0 is the element x itself. Otherwise element at push x, l if the position is not 0 it is some next of p for some position p then the element at position next p in the list obtained by pushing x, l is the element in the list l at position p. So notice that in this definition the element position changes when I push an element in a list. So the element at position p in push x, l is not necessarily equal to the element in at position p in the list l. So at 0th position for example when I push x in l x takes the 0th position whereas the original element which was at 0th position in l goes to position 1 in the new list obtained by pushing x in the list. So here is another operation called insert which inserts an element x in the list l at position p. So insert 5, 0 x in the empty list if I want to insert at position 0 we just push x in the element in the empty list to get a list containing just x. In the empty list if I want to insert at any non-zero position then there is no such position at which we can insert so we say it is undefined. So inserting in an empty list at position next p is undefined for any element x. Now if you are inserting in a non-empty list push y, l at position 0 the element x we simply push x into that list so its value is push x, push y, l otherwise if you are inserting at a position next of p in the list push y, l next p y then we keep y at the 0th position. So this is obtained by pushing y in the list obtained by inserting in list l at position p the element x. So this essentially inserts an element x at position p and shifts all the elements right one position those that come after position p get shifted right by one. Similarly we can define the delete operation which deletes the element at position p from l. Deleting from an empty list is undefined for all positions there is no element at any position in the empty list. Delete from the 0th position in from the list obtained by pushing x from l gives the list l itself. So effectively removes the first element of the list. If the list is not empty and we are deleting from the position next of p from that list then essentially we keep the first element as it is and delete from l from the position t. So let us look at another function called first occurrence lx which returns the position at which x occurs in the list l for the first time and it is undefined if x does not occur in the list l at all. So first occurrence empty list x is undefined empty list does not contain any element. So first occurrence of x in a list obtained by pushing y l pushing y in list l is 0 if x is equal to y. If the first element of the list itself is x then the position is 0 otherwise we find the first occurrence in l of x and return the next of that. So the position will be one more than the position of x in the list l. So next of first occurrence of l comma x returns the position at which x occurs for the first time in l. So we can define functions on lists also using these operations. So either you can define functions using the standard way which is to define it for the empty list and assuming it is defined for a list l define it for a list obtained by pushing an element in l otherwise we can use the already defined operations on list and we can write more in a programming style the definition which gives a nutritive way of defining the function rather than a recursive. So for example finding the length of a list the length function can be defined as I define a variable called position whose value is 0. So remember positions are just numbers so we can assign a value to the position p which is 0 and now while there exists an element in list l at p we set p equal to next p that is while there is an element at position p we keep incrementing p till you reach a point where there is no element in list l at position p. So remember element at l p will be undefined when there is no element in l at position p and this will happen only when p becomes equal to the length of the list and so we return p. So this is the length function now here is another function which extracts a substring from a list l starting from position p and position q so it excluding the position q so it finds the sequence of elements in the list l starting from position p to position q but not including q. So again we will create a new list in which we will essentially copy the elements from the list l so set position p1 equal to p initially and p2 equal to 0 we set a list l equal to the empty list and while the position p1 is less than q and element at l p1 is not undefined there exists an element in l at position p1 we insert in s at position p2 whatever that element in l was at position p1. Then increment p1 and increment p2 as well so we will keep inserting in s will be an empty list in which we will keep inserting one element at after another at successively increasing position starting from 0 and position p1 will start from p and as long as p is less than q it will keep inserting the elements in s only thing is if say p was greater than q then the substring is not defined at all then we will not insert anything in the list l and similarly if the position q specified is after the end of the list l so that is at some point we get the element at position p1 in l is undefined then we will not consider it as a proper substring. So finally only when p1 is equal to q we will return the substring s else we will return it as undefined the substring is not defined at all. So here we are essentially using of the already defined operations on list rather than defining it using the standard way of looking at the empty list and the list obtained by pushing one element. So we can try many different functions now using these operations so as exercise we can try to write a function to count the number of distinct elements in a list. So you can do this in two way one is defining the using the standard way of defining operation define it for the empty list assuming its list l define it for a list obtained by pushing an element x in l otherwise we can also write an iterative function which uses the already defined operations on list which allows you to access elements at this different positions in the list and we can write a function in a programming style which does the same thing. You can try to see which way you find easier of the two both of them are defined ways of defining this function but some ways are more convenient than others for different functions. So here are some more exercises so suppose I delete consider the list obtained by inserting at position p and element x in the list l and I delete the element at position p will I always get back the list l. So I insert an element x at position p and delete from the resulting list delete the element at position p show that this will always give you the same list provided these functions are well defined. So if the position p is well defined in the list l then show that this will always be true also write a function to change the element at position p in a list l to x. So if l does not already have an element at position p this should be undefined otherwise it changes the value of the element at position p in the list to x. So this is different from inserting the element at x we are essentially replacing the original element by a new element rather than adding a new element to the list. So try these as exercises and we will continue further later. Thank you.