Presentation is loading. Please wait.

Presentation is loading. Please wait.

These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else These notes are provided free of charge and may.

Similar presentations


Presentation on theme: "These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else These notes are provided free of charge and may."— Presentation transcript:

1

2 These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else These notes are provided free of charge and may not be sold in any shape or form Material from these notes is obtained from various sources, including, but not limited to, the following: Data Structures and Abstractions with Java, 2nd, 3rd and 4th Editions by Frank Carrano (and Timothy Henry) Data Structures and the Java Collections Framework by William Collins Classic Data Structures in Java by Timothy Budd Java By Dissection by Pohl and McDowell Java Software Solutions (various editions) by John Lewis and William Loftus java.sun.com and its many sub-links

3 Lecture 22: Intro to Trees
Consider the primary data structures that we have examined so far: Array, ArrayList, LinkedList (also informally Stack and Queue – more on these later) All of these have been LINEAR data structures Data is organized such that items have a single predecessor and a single successor Except first (no predecessor) and last (no successor) We can draw a single "line" through all elements Note: We also covered the Bag, which is not necessarily linear, but both of our implementations were linear These data structures have worked well, but… Can we benefit from organizing the data differently? We will come back and talk about Stacks and Queues later

4 Lecture 22: Intro to Trees
Tree structures In a linked list, each node had a reference to at most one previous and one next node What if we allowed nodes to have references to more than one next node? Root Node – has no parent node Interior Node – has a parent and at least one child node Doubly linked lists have a previous reference – we mentioned them briefly Leaf Node – has no children

5 Lecture 22: Intro to Trees
A tree is a non-linear data structure, since we cannot draw a single line through all of the elements Some more definitions: For any node V, if P = parent(V), then V = aChild(P) For any node V, the descendants of V are all nodes that can be reached from V Parent(V) V siblings (all have same parent) s s s Descendants of V

6 Lecture 22: Intro to Trees
For any node V, the subtree rooted at V is V and all of its descendants From V's point of view this is a tree in itself Now we can define a tree recursively: T is a tree if T is empty (no nodes) – base case, or T is a node with 0 children – base case or 1 or more children that are all trees – recursive case Do example on board

7 Lecture 22: Intro to Trees
How do we represent an arbitrary tree? We can have a node with data and an adjacency list of children Draw on board Note that the number of children can be arbitrary List could be long if node has many children We can have a node with data, and two references, One to left child and one to right sibling Number of children can still be arbitrary List can still be long Shows the levels of the tree better You will likely see these representations in more detail in CS 1501

8 In many applications, we can limit the structure of our tree somewhat
Lecture 22: Binary Trees In many applications, we can limit the structure of our tree somewhat BINARY TREE A tree such that all nodes have 0, 1, or 2 children Recursive definition: T is a binary tree if T is empty (base case) or T is a node with the following structure where element is some data value where left and right are binary trees left element right

9 Lecture 22: Binary Tree Properties
Consider a binary tree with n nodes: Height of the tree is the maximum number of nodes from the root to any leaf Tree to right has a height of 6 We can also think of heights of subtrees of trees Subtree rooted at X has a height of 3 Height is an important property Many binary tree algorithms have run- times proportional to the tree height Let's establish some bounds on height x Some definitions start at 0

10 Lecture 22: Binary Tree Properties
Maximum Height: Given a binary tree with n nodes, what is the maximum value it could have for its height How would the maximum height tree look? Discuss and see notes below Minimum Height: Given a binary tree with n nodes, what is the minimum value it could have for its height? Assume for simplicity that n = 2k-1 for some k How would this minimum height tree look? How can we justify its height value? Discuss Maximum height tree would be a linear tree – every node has one child (except the last, sole leaf). This tree would have a height of n given an n-node tree.

11 Lecture 22: Binary Tree Properties
A minimum height tree will have the maximum branching at each node Given n = 2k-1, this tree will be a Full Tree All interior nodes have 2 children All leaves are on the same, last level of the tree Ex: Tree on bottom of this slide is a full tree of height 3, and it has 23-1 = 7 nodes So how can we relate n (7) to the height (3)? Note the number of nodes at each level of a full tree: Level 1: 1 node = 20 Level 2: 2 nodes = 21 Level 3: 4 nodes = 22 Level i: 2i-1 nodes The total number of nodes is the sum of the nodes at each level

12 Lecture 22: Binary Tree Properties
Recall that n = 2k-1 for some k Recall (from the last slide) that n = … + 2h-1 for some h Note that h is the height of the tree, so if we can solve for h we are done Thus, we get 2k-1 = n = … + 2h-1 for some h Using math, we know that … + 2h-1 = 2h-1 (geometric sum) Now we have 2k-1 = 2h-1 Adding 1 to both sides we get 2k = 2h Taking the log2 of both sides we get h = k

13 Lecture 22: Binary Tree Properties
But we want the height in terms of the number of nodes, n: 2k-1 = n 2k = n+1 k = log2(n+1) So the minimum height of a binary tree with n nodes = h = k = log2(n+1) Note this is for a tree with 2k-1 nodes Binary trees can have any number of nodes – will this change the formula? Not significantly More generally we can say that the minimum height for a tree with n nodes is O(log2n) Now we also know that a Full Tree of height h has 2h-1 nodes

14 Lecture 22: Binary Tree Properties
Note that most trees CANNOT be Full Trees, since all Full Trees have 2i-1 nodes (1, 3, 7, 15, etc) However, a tree with ANY number of nodes can be a Complete Binary Tree A complete tree is a full tree up to the second last level with the last level of leaves being filled in from left to right If the last level is completely filled in, the tree is Full A Complete Binary Tree of height h has between 2h-1 and 2h-1 nodes A nice property of a complete binary tree is that its data can be efficiently stored in an array or vector Do demo on board We will see why this is nice when we discuss PQs

15 Lecture 23: Height of a Binary Tree
So how do we find out the height for a given tree? We can define this recursively as well: Height(T) If T is empty, return 0 else Let LHeight = Height of left subtree Let RHeight = Height of right subtree Return (1 + Max(LHeight, RHeight)) Let's look at an example Tree we looked at previously in Slide 277

16 Lecture 23: Height of a Binary Tree
Trace on board with class

17 Lecture 23: Representing a Binary Tree
We'd like to be able to do operations on binary trees Implement the height that we just discussed Traverse the tree in various ways Find other properties Max or min value Number of nodes Before we can do these we need to find a good way to represent the tree in the computer

18 Lecture 23: Representing a Binary Tree
We'll do this in an object-oriented way, as we did with our lists It is a bit complicated, so we need to pay attention to all of the steps public interface TreeInterface<T> { public T getRootData(); public int getHeight(); public int getNumberOfNodes(); public boolean isEmpty(); public void clear(); } Note that this interface is for general trees Let's make it more specific for binary trees

19 Lecture 23: Representing a Binary Tree
public interface BinaryTreeInterface<T> extends TreeInterface<T>, TreeIteratorInterface<T> { public void setTree(T rootData); public void setTree(T rootData, BinaryTreeInterface<T> leftTree, BinaryTreeInterface<T> rightTree); } This simply allows for an "easy" assignment of binary trees We'll look at TreeIteratorInterface<T> later Now we have the basic functionality of a binary tree – but we need to get the basic structure We'll talk about the iterators later

20 Lecture 23: Representing a Binary Tree
Recall our linked list data structures: The "building blocks" for our lists were Node objects that we defined in a different class This class could be separate For re-use / flexibility This class could be an inner class For access convenience We will do something similar for our binary trees We will define a BinaryNode class to represent the inner structure of our tree This will be more complex than our Node class for LLs because there are more things needed to manipulate our binary tree nodes

21 Lecture 23: Representing a Binary Tree
class BinaryNode<T> { public T getData(); public void setData(T newData); public BinaryNode<T> getLeftChild(); public BinaryNode<T> getRightChild(); public void setLeftChild(BinaryNode<T> newLeftChild); public void setRightChild(BinaryNode<T> newRightChild); public boolean hasLeftChild(); public boolean hasRightChild(); public boolean isLeaf(); public int getNumberOfNodes(); public int getHeight(); public BinaryNode<T> copy(); } Gives the basic functionality of a node Note lack of data – we will look at this soon

22 Lecture 23: Representing a Binary Tree
Summary so far: TreeInterface TreeIteratorInterface Give the basic functionality of a tree BinaryTreeInterface Adds a couple of methods for binary trees Interfaces give us the ADTs Now we need some classes to implement these interfaces BinaryNode class Gives us the underlying structure

23 Lecture 23: Representing a Binary Tree
class BinaryNode<T> { private T data; private BinaryNode<T> leftChild; private BinaryNode<T> rightChild; // See .java file for methods // (also in Slide 294) } Self-referential, just as linked list nodes However, can now branch in two directions Now we can easily define a binary tree We will also have some additional methods to manipulate / access our tree

24 Lecture 23: Representing a Binary Tree
public class BinaryTree<T> implements BinaryTreeInterface<T> { private BinaryNode<T> root; // See .java file for methods } Idea: A BinaryTree has one instance variable – a reference to a BinaryNode A BinaryNode has 3 instance variables An reference to T to store data for that node Left and right references to subtree nodes Creation by Composition To manipulate a BinaryTree we must manipulate its underlying nodes

25 Lecture 23: Representing a Binary Tree
We will come back to the BinaryTree<T> class later on For now we will look at the BinaryNode<T> class and see how some of the operations are done Finding the height, traversals, etc. We will then see how these operations will be used for our BinaryTree<T> class So consider the BinaryNode<T> class…

26 Lecture 23: Implementing Some Operations
Ok, let's first look at code that determines the height for a BinaryNode: public int getHeight() { return getHeight(this); } // call rec. version private int getHeight(BinaryNode<T> node) { int height = 0; if (node != null) height = 1 + Math.max(getHeight(node.getLeftChild()), getHeight(node.getRightChild())); return height; } Note that actual code is not really different from the pseudocode we looked at in Slide 288 and that we already traced

27 Lecture 23: Implementing Some Operations
How about copying a tree? Copying an array or linked list is fairly simple, due to their linear natures However, it is not immediately obvious how to copy a binary tree such that the nodes are structurally the same as the original Luckily, recursion again comes to the rescue! If we view copying the tree as a recursive process, it becomes simple! To copy tree T, we simply Make a new node for the root and copy its data Recursively copy the left subtree into the left child Recursively copy the right subtree into the right child

28 Lecture 23: Implementing Some Operations
Let's now look at code for copy(): public BinaryNode<T> copy() { BinaryNode<T> newRoot = new BinaryNode<T>(data); if (leftChild != null) newRoot.setLeftChild(leftChild.copy()); if (rightChild != null) newRoot.setRightChild(rightChild.copy()); return newRoot; } // end copy Note the similarities (and differences) to the code for getHeight() Both are essentially traversing the entire tree, processing the nodes as they go

29 Lecture 23: Trace of copy() method
BinaryNode<Integer> T2 = T1.copy() public BinaryNode<T> copy() { BinaryNode<T> newRoot = new BinaryNode<T>(data); if (leftChild != null) newRoot.setLeftChild(leftChild.copy()); if (rightChild != null) newRoot.setRightChild(rightChild.copy()); return newRoot; } // end copy T2 this newRoot newRoot.leftChild newRoot.rightChild T1 10 this newRoot newRoot.leftChild newRoot.rightChild 10 20 30 20 30 this newRoot 40 50 40 50 Note: View this in a ppt slideshow to see the animation

30 Lecture 24: Binary Tree Traversals
So what about traversing itself? Again, unlike linear structures (array, linked list) it is not obvious However, if we think recursively, we can still do it in a fairly easy way: Consider a tree node T I can traverse the subtree rooted at T if I Traverse T's left subtree recursively Visit T itself (i.e. access its data in some way) Traverse T's right subtree recursively left Data right Do an example on the board

31 Lecture 24: Binary Tree Traversals
There are 3 common traversals used for binary trees They are all similar – the only difference is where the current node is visited relative to the recursive calls PreOrder(T) if (T is not empty) Visit T.data PreOrder(T.leftChild) PreOrder(T.rightChild) InOrder(T) InOrder(T.leftChild) InOrder(T.rightChild)

32 Lecture 24: Binary Tree Traversals
PostOrder(T) if (T is not empty) PostOrder(T.leftChild) PostOrder(T.rightChild) Visit T.data Let's look at an example We'll traverse a tree using all 3 to see how it proceeds and what output it generates 50 Do traces on board 30 80 10 40 90 5 20 45 85 95

33 Lecture 24: Binary Tree Traversals
Note that in the example shown, the InOrder traversal produces the data IN ORDER This is NOT ALWAYS the case – it is only true when the data is organized in a specific way If the tree is a Binary Search Tree – we will see this later The actual code for these traversals is not any more complicated than the pseudocode See BinaryNode.java and Example14.java It uses one tree that is NOT a BST and one that is Note how the work is done through the recursive calls The run-time stack "keeps track" of where we are Runtime of these traversals? Discuss and see note below The runtime is O(N) since a recursive call is done for each of the N nodes and the instructions executed per node (other than the recursive calls) are constant (just a simple visit). Note that more than N calls of the traversal methods are actually done, since we have a call for each base case, which is an empty node. However, with N nodes in a binary tree, we will always have N+1 "empty" nodes (i.e. null references) so the Big-O value will still be O(N).

34 Lecture 24: Binary Tree Traversals
Note again how the traversals, getHeight() and copy() are all similar In fact all of these methods are traversing the tree They differ in the order (pre, in, post) and what is done at each node as it is visited For example: getHeight() can be thought of as a postorder traversal, since we have to get the height of both subtrees before we know the height of the root copy() is actually a combo of all 3 orderings The root node is created preorder The left child is assigned inorder The right child is assigned postorder

35 Lecture 24: Binary Tree Traversals
Can these traversals be done iteratively? Yes but now we need to "keep track" of where we are ourselves We do this by using our own stack of references The idea is that the "top" BinaryNode reference on our stack is the one we are currently accessing This works but it is MUCH MORE COMPLICATED than the recursive version The author uses the iterative versions these traversals to implement iterators of binary trees We will see how much harder these are to do iteratively However, we can't use the recursive version for an iterator, since it needs to proceed incrementally

36 Lecture 24: Binary Search Trees
Binary Trees are nice, but how can we use them effectively as data structures? One way is to organize the data in the tree in a special way, to create a binary search tree (BST) A BST is a binary tree such that, for each node in the tree All data in the left subtree of that node is less than the data in that node All data in the right subtree of that node is greater than the data in that node Note that this definition does not allow for duplicates. If we want to allow duplicates we should add "or equal to" to one of the above lines (but not both)

37 Lecture 24: Binary Search Trees
Naturally, we can also define BSTs recursively: A binary tree, T, is a BST if either T is empty (base case) or T is a node with the following structure where all values in the tree rooted at left are less than data where all values in the tree rooted at right are greater than data where left and right are BSTs left data right

38 Lecture 24: Binary Search Trees
50 BST 30 80 10 40 90 5 20 45 85 95 50 NOT A BST Note that the shape of the tree is unrelated to the BST property. BSTs can be full, linear or anywhere in between. BST 30 50 10 30 80 10 40 20 90 5

39 Lecture 24: BST Interface
Let's back up a bit now We haven't defined the BST ADT yet (i.e. the methods that make up a BST): Actually, the text defines a more general SearchTreeInterface, which our BST will implement: public boolean contains(T entry) Is an entry in the tree or not? public T getEntry(T entry) Find and return and entry that "equals" the param entry If the key matches return the object; otherwise return null

40 Lecture 24: BST Interface
public T add(T newEntry) Add a new entry into the tree New object is put into its appropriate location, keeping the search property of the tree intact If an object matching newEntry is already present in the tree, replace it and return the old object What if we don't want to replace it? Implications? public T remove(T entry) Remove entry from the tree and return it if it exists; otherwise return null public Iterator<T> getInorderIterator() Return an iterator that will allow us to go through the items sequentially from smallest to largest Go back and look at Iterator<T> interface

41 Before we discuss the implementation details
Lecture 24: BST Search Before we discuss the implementation details Let's get the feel for the structure by seeing how we would do the getEntry(T entry) method Consider a recursive approach (naturally): What is our base case (or cases)? If tree is empty – not found else if key matches node value -- found What are our recursive cases? If key < node value, search left subtree else if key > node value, search right subtree How do we use our recursive results to determine our overall results? Simply pass result from recursive call on Trace an example

42 Lecture 24: BST Search vs. Sorted Array Search
Notice the similarity between this algorithm and the binary search of a sorted array This is NOT coincidental! In fact, if we have a full binary tree, and we have the same data in an array, both data structures would search for an item following the exact same steps Let's look for item 45 in both data structures: 1 2 3 4 5 6 10 30 40 50 70 80 90 2 3 1 50 1 30 80 2 10 40 70 90 3

43 Lecture 24: BST Search vs. Sorted Array Search
In the case of the array, 45 is "not found" between 40 and 50, since there are no actual items between 40 and 50 In the case of the BST, 45 is "not found" in the right child of 40, since the right child does not exist Both are base cases of a recursive algorithm Same runtimes since the height of a full tree is O(log2n) Immediately, we see an advantage of the BST over the LinkedList Although access to nodes requires references to be followed, the tree structure improves our search time from O(n) to O(log2n) Ok, now is a BST also an improvement over the array?

44 Lecture 24: BST Implementation
To answer that question, we need to look at some more operations Let's first look more at the BST structure BST Implementation We will use the BinaryTree as the basis We can implement it either recursively or iteratively We'll look at both versions public class BinarySearchTree<T extends Comparable<? super T>> extends BinaryTree<T> implements SearchTreeInterface<T>

45 Lecture 24: BST Implementation
We will concentrate on four things: getEntry() method contains() can be easily derived from getEntry() add() method remove() method getInorderIterator() method These provide the basic functionality of a Binary Search Tree: Finding an object within the tree Adding a new object to the tree Removing an object from the tree Traversing the tree to view all objects

46 Lecture 24: BST Implementation
getEntry() We already discussed the idea of this method in a recursive way Now let's look at the actual code and trace it See recursive BinarySearchTree.java See iterative BinarySearchTree.java Note how iterations of the loop correspond to recursive calls See how contains() is easily derived

47 Lecture 25: BST Implementation
add() This one is more complicated Special case if tree is empty, since we need to create a root node Otherwise, we call addEntry(), which proceeds much like getEntry() However, we have more to consider. Consider possibilities at current node (call it temp): New data is equal to temp.data Store old value, assign new value and return old node New data is less than temp.data If temp has a left child, go to it else add a new node with the new data as the left child of temp

48 Lecture 25: BST Implementation
New data is greater than temp.data If temp has a right child, go to it else add a new node with the new data as the right child of temp Of course, the actual code is trickier than the pseudocode above Let's trace the recursive version to see how it works See recursive version of BinarySearchTree.java One interesting difference from getEntry()/findEntry() The base case for addEntry() must be at an actual node We cannot go all the way to a null reference, since we must link the new node to an existing node If we go to null we have nothing to link the new node to Thus we stop one call sooner for the base case for addEntry()

49 Lecture 25: BST Recursive addEntry() Method
Adding 25 to the BST Note: Run-Time Stack goes downward in this case rootNode 25<50, go left root rootNode 25<30, go left 50 30 80 rootNode 25>10, go right 10 40 90 rootNode 25>20, right null 5 20 45 85 95 Note: Author's code is a bit inconsistent with regard to local variables. When going left, a new variable, subTreeRoot is used to temporarily store the result of the recursive call. However, when going right, the rightChild variable is simply reassigned. 25 To see this correctly you must run it in a Powerpoint slideshow

50 Lecture 25: BST add() Method
This is elegant but it still it (obviously) requires many calls of the method As we know, this adds overhead to the algorithm If we do the process iteratively, this overhead largely goes away See iterative version Trace As with findEntry(), since the recursive calls are "either" "or" but not both, the iteration is very simple and actually preferred over the recursion We are not traversing the entire tree but rather just following a single path down from the root

51 Lecture 25: BST remove() Method
Idea is simple: 1) Find the node and, 2) Delete it However, it is much trickier than add – why? Unlike add(), which is always at a leaf, the remove() operation could remove an arbitrary node Depending upon where that node is, this could be a problem Let's look at 3 cases, and discuss the differences between them node has 2 children node has 1 child node is a leaf Trace on board

52 Lecture 25: BST remove() Method
Node is a leaf This one is easy – simply set its parent's appropriate child reference to null (so we need a ref. to parent) Garbage collector takes care of the rest Node has one child Still not so bad…in fact this looks a lot like what? Deleting a node from a linked list Set parent's child reference to node's child reference Node has two children This one is tricky! Why -- only one reference coming in but two going out

53 Lecture 25: BST remove() Method
So to actually delete the node would require significant reorganization of the tree But do we really even need to delete the NODE? No, we need to delete the DATA Perhaps we can accomplish this while leaving the node itself where it is How? Recall that what is important about a BST is the BST Property (i.e. the ordering) The shape is irrelevant (except for efficiency concerns, which we will discuss next) So perhaps we can move data from another node into the node whose value we want to delete Perhaps the other node will be easier to delete We saw a simplified form of this same idea very early in the term when we deleted from a LinkedBag

54 Lecture 25: BST remove() Method
How do we choose this node? Consider an inorder traversal of the tree We could substitute the value directly before (inorder predecessor) or the value directly after (inorder successor) How to find this node? Consider inorder predecessor – it is the largest value that is less than the current value So we go to the left one node, then right as far as we can Show on board What if this node also has two children? Will not ever – since we know by how we found it that it has no right child

55 Lecture 25: BST remove() Method
Let's look at the code to see how this is done We'll look at the iterative version Recursive version works, but due to the same issues we discussed for add(), we will prefer the iterative version Note that the code looks fairly tricky, but in reality we are just going down the tree one time, then changing some references A lot of the complexity of the code is due to the author's object-oriented focus

56 Lecture 25: Deleting a Node with 2 Children from a BST
50 30 25 80 10 40 90 5 20 45 85 95 30 is found It has two children Find Inorder Predecessor Go left Go right until null Overwrite current node with inorder predecessor Delete inorder predecessor 25 To see this correctly you must run it in a Powerpoint slideshow

57 Lecture 25: BST getInoderIterator() Method
getInorderIterator() As we discussed previously, this will be a step-by-step inorder traversal of the tree Recall idea of iterator from lists It is done iteratively so that we can pause indefinitely after each item is returned Still the logic is much less clear than for the recursive traversals This method is implemented in the BinaryTree class, so we don't have to add anything for BinarySearchTree See BinaryTree.java

58 Lecture 25: BST getInorderIterator() Method
What data and methods do we need? Method simply returns an instance of private InorderIterator object Recall the methods we need for an iterator() hasNext() – is there an item left in the iteration? next() – return the next item in the iteration We also need some instance variables To mimic the behavior of the run-time stack, we will use our own Stack object Plus we need a BinaryNode to store the current node How will it work? Think about behavior of inorder traversal We need to duplicate this iteratively

59 Lecture 25: BST getInorderIterator() Method
Initially (in the constructor), set the currentNode to the root For each call of next() Go left from root as far as we can, pushing all nodes onto the stack Top of the stack will be the next value in the iteration (nextNode) Then set the currentNode to the right child of nextNode After nextNode we should traverse the its right subtree That is what currentNode now represents It could be null – in this case the previous node had no right subtree, and we backtrack Let's trace this execution

60 Lecture 25: BST getInorderIterator() Method
nodeStack root 50 30 80 currentNode 10 40 90 nextNode 5 20 45 85 95 To see this correctly you must run it in a Powerpoint slideshow Trace is only partially shown (up to 40)

61 Lecture 26: BST Run-times
So how long will getEntry() (and contains()), add() and remove() take to run? It is clear that they are all proportional in run-time to the height of the tree So if the BST is balanced getEntry(), add() and remove() will all be O(log2N) If the BST is very unbalanced getEntry(), add() and remove() will all be O(N) Given normal use, the tree tends to stay balanced However, it could be unbalanced if the data is inserted in a particular way Ex: If we do add()s of sorted data from a file

62 Lecture 26: BST Run-times
Thus, in the AVERAGE CASE, BST give us O(log2N) for Find, Insert and Delete In the WORST CASE, BST gives us O(N) for Find, Insert and Delete So how does a BST compare to a Sorted array or ArrayList? Recall that a sorted array gives us (average) O(log2N) to find an item using binary search O(N) to add or remove an item (due to shifting) Thus, in the average case, BST is better for Insert and Delete and about the same for Find

63 Lecture 26: Balanced BSTs
"On average", a BST will remain balanced But it is possible for it to become unbalanced, yielding worst case run-times Can we guarantee that the tree remains balanced? Yes, for example the AVL Tree (Chapter 27) When Inserts or Deletes are done, nodes may be "rotated" to ensure that the tree remains balanced However, these rotations add overhead to the operations If we time the operations, on average it is actually slower than the regular BST


Download ppt "These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else These notes are provided free of charge and may."

Similar presentations


Ads by Google