 Hello everyone, so we're in our binary search tree handout right now We're going to dig into this thing a little bit more and see how it works So as a reminder a binary search tree is a binary tree Meaning every node has at most two children a binary tree in which each data value is greater than all its left Descendants and less than all its right descendants. So this is an example of a binary search tree, right? Because here's eight eight is the root of this tree the root node And you can see just at a glance that it is greater than all of its left descendants and eight is less than all of its right descendants okay, so What we will want to do is we want to create one of these binary search trees in code And use it as a data structure because it has some interesting properties What we are going to use it for specifically is to implement another version of the map Right, so you used an assignment 7 you used a hash table to create a map and a map is like a dictionary in Python Hash table was good. It had some upsides to it You can insert usually in big O of 1 you can search in big O of 1 The downside to the map that we didn't a hash map that we didn't talk about is deleting from the hash map deleting from the map a hash table is not so trivial So what we are going to do is we're going to implement another map with kind of the same dictionary behavior But using this data structure And that this data structure the binary search tree has a few advantages one It's always sorted right so if you kind of look at this tree from left to right You'll see it's sorted which is nice the hash table isn't sorted And it's there's no wasted space in a binary search tree At least not the way we are going to implement it in a hash table You've got to have all these empty slots and every once in a while You've got to resize the thing and resizing is expensive the binary search tree. We're not going to waste any space whatsoever All right, so the way we're going to do that is with nodes, right? So the binary search tree is going to have these things called tree nodes in them and the tree nodes are going to hold some Data that we care about and then they're going to have a left child and a right child Okay, so with the binary search tree. We need to be able to do a few different things, right? So we want to be able to insert into the tree And that's what we'll talk about now. We need to be able to delete from the tree Get things out of it. That's something again. We didn't touch with hash tables We want to be able to search it And then the final thing we need to be able to do is we're going to traverse the tree right traversing means we visit every node and There may be good reason for us to do that like if we want to print out the contents of the tree We're going to have to visit every node. All right, but we're going to start by talking about insert inserting into the tree We are going to implement this using a recursive algorithm And the reason for that is that you can define the whole tree itself recursively, right? The tree is the root node The left subtree and the right subtree And no matter what node you look at you can say hey It's me my current node and then my left subtree in my right subtree So all the algorithms that we write for insert delete search and traverse We are going to implement them recursively because it's a more natural way to think about this data structure You can't implement them iteratively, but the code is not nearly as neat. Okay, so we're going to do recursive algorithms Before we get into the algorithm for putting data for inserting into this tree Let's just make sure we're real clear on conceptually what that means. Okay, so here's a binary search tree and We're going to insert into it Right now the property of the binary search tree that we have to preserve is that everything to the left of the node is Less than it and everything to the right of the node is greater than it. Okay, so What will the tree above look like after performing the following inserts in order, right? So just glancing at this tree when you can see the whole tree You can probably figure out well one is probably going to go over here, right? but You're the computer when you derive an algorithm for inserting the computer is not omniscient It doesn't know the whole status of the tree. In fact the computer whenever it starts It only knows about the root. Okay, the root of the tree and So how can we create an algorithm that starting with the root of the tree figures out where this goes? Well, because this is a binary search tree We know that everything to the left of eight in its eights left child is less than it and everything in Eights right child must be greater than it. Okay, so Start with one Let's ask you the very simple question is one less than eight. Yes So we're going to take a look at eights left child. Well eight does have a left child So we need to go pay it a visit Okay, so we go over to five is one less than five. Yes. Okay, let's take a look at Fives left child. All right, there's something there. So we need to go visit it. We go to three is One less than three Yes All right. Does three have a left child? No. No, it does not Okay, and what we are going to do is our goal when we insert is to insert a leaf node Okay, so I'm gonna grab My leaf over here off the screen put it over here Okay, so every time we insert we are going to insert as a leaf node We do not want to upset the tree. Okay, so at no point Are we gonna like say we were inserting ten? We are not gonna like unhook eight from eleven Hook it up to ten and then ten to eleven. We're not gonna do that too much work We're gonna instead just go down to the tree Until we find where one should go where a node should go and shove it in as a leaf. Okay So let's do it with negative one. Where does negative one go? Negative one is less than eight. So we go left less than five go left less than three go left less than one Well, we can't go left because there's nowhere to go One has no left a child. So that is where we're gonna put negative one All right, so take a minute pause right here and insert these values Okay, 14 6 and 9 in that order. So while you're figuring that out. I'm gonna copy them over So 14 is not less than eight. It's greater than eight. So we got to visit the right child So 14 go visit the right. It's 11. 14 is greater than 11. So we got to go visit 15 14 is less than 15. So we go to 15's left child, but they don't have a left child So that's where we go 14 becomes a left child there 6 Gonna go here 9 It's going to be I want to copy one thing over there. Sorry about that nine is gonna wind up Here, okay, so this is what our tree will look like now I'll encourage you I want you to go ahead and do questions two three five four five six seven and eight Pause here for a second while you do that and answer these with respect to this completed tree Okay, so pause the video work through these real fast right the height of this tree the height is The depth of the deepest node in the tree So just glancing at this negative one is the deepest node and what's the depth? The depth is the number of edges between the deepest node and the root Okay, so to get from negative one to the root we got to go up one two three four steps So the height of this tree The height is the depth of the deepest node and the depth of the deepest node is four The depth of 14 is one two three The depth of eight Well eight is the root and the depth of the root is always zero because there's no past edges between the root and itself Does node three have any siblings? Well to answer that question you look at three's parent Which is five and we see that five does have another child seven so three sibling Is seven because they share the same parent the right subtree of 11 is going to be 15 and 14 Subtree is everybody all of 11's right descendants What does the binary search tree look like if the data is inserted in ascending order? So one two three four five, right? So you're going to get a tree where One is at the root And then it's right child is two and two's right child is three and three's right child is four and four's right child is five Conversely, what does the binary search tree look like if data is inserted in descending order? All right, so we first we're talking about inserting five And then four four is less than that three is less than four two is less than three one is less than two So we get these chains right if we're doing an order Insertions, we get these chains that are basically lists. We don't have a tree looking thing. It's a chain of things Um Does every unique arrangement of data values yield a distinctively just shaped tree? No, not necessarily if you insert these two things like in these in this order they will both Um Look like this, right? So the order that you insert the values Uh, there's not guaranteed to give you a uniquely shaped tree All right, so, um, what is the worst case scenario for the binary search tree? Well, the worst case scenario are these scenarios right here when you Insert the elements in order or reverse order, right? Because then you don't get a tree and we want that tree shape It's the tree shape. It's like this kind of balanced shape That's going to make our algorithms or divide and conquer algorithms insert search. It's going to make them Uh efficient, but if the shapes look like this Right, these are effectively linked lists And so if you want to go find say five in here, you've got to look through one two three four five nodes okay, so Um, what is the big O of insert? Well in the worst case big O then in a worst case But it'll be if this tree is nice and balanced if all the leaves are filled out if it is a complete tree in other words if every child if every node Has two children before going on to the next row Then Your insert will be big O log base two of then In the best case, right? So we're at a point where we need to start thinking about best case scenarios and worst case scenarios, all right So, um, what I would like you to do is create a tree a binary search tree Using the names of the characters in your first name Okay, the lesser of two characters is the one nearest to a an alphabet So use the characters of your first name create a binary search tree Um using alphabetical comparison, right? Just make sure you really understand how insert works, right? So this has been our algorithm, right our algorithm is we start at the root And then we say is the thing we're inserting less than or greater than And depending on that answer we either go left or right and ask that same question Is the thing greater than or less than and we stop Whenever we find hey, I want to go left or right, but there's nothing there I've hit a place where I can insert a leaf node And that's going to be our algorithm. Okay, so if the item is less the item We want to put in is less than the data. That's good Okay Now we need to ask the question. All right. I want to put it in is there room to put it in, right? So when I got to four, right say I need to insert the value Three and a half, right Is this empty if so put three and a half here So if current dot left is none Then yeah, put it there current dot left gets your new tree node With the item in it. Okay, but if it's not Empty right if there is something here like I want to insert six Well, I can't insert it here because it's not empty. So what do I want to do? Well, I need to get down to this point here, but how can I do that? I just go over here and I say insert six here and figure out where it goes Okay, so we go left By simply calling recursively insert Curr dot left the item if the data is greater than current data We go right, right? So if curr dot right is none Insert it if they use red to be consistent show that I added them. Okay Curr dot right is none. There's space I'm trying to insert something greater than the current node and he has no right child So put him there. Otherwise. Oh, he's already got a right child. Well, let me go into that right child and try and insert from there Okay, so else Insert into the right child the item. Okay, and that's it nice elegant algorithm It's recursive. It's got two base cases When the curr dot left is none and when the curr dot right is none otherwise Call insert on the subtree, right? So this is our algorithm. Let's hop over to the code and start writing some code