Anda di halaman 1dari 20

7/16/2019 10.

Balanced Binary Search Trees — Data Structures and Algorithms with Python

Data Structures and Algorithms with Python


P R E VIOUS | N E X T | I N D EX

10. Balanced Binary Search Trees


In chapter 6 binary search trees were defined along with a recursive insert algorithm. The
discussion of binary search trees pointed out they have problems in some cases. Binary search
trees can become unbalanced, actually quite often. When a tree is unbalanced the complexity
of insert, delete, and lookup operations can get as bad as \Theta(n). This problem with TABLE OF CONTENTS
unbalanced binary search trees was the motivation for the development of height-balanced
AVL trees by G. M. Adelson-Velskii and E. M. Landis, two Soviet computer scientists, in 1962. 1. Python Programming 101
AVL trees were named for these two inventors. Their paper on AVL trees [avltrees] described 2. Computational Complexity
the first algorithm for maintaining balanced binary search trees. The chapter goes on to
discuss Splay Trees as another example of balanced binary search trees. 3. Recursion

4. Sequences
10.1. AVL Tree Implementations 5. Sets and Maps

6. Trees
AVL trees maintain their own balance. The balance can be maintained in one of two ways.
Either the height of each node in the tree can be maintained or the balance of each node in 7. Graphs
the tree can be maintained. If maintaining the height, there is a little more work to be done to 8. Membership Structures
adjust heights all the way up the tree. If balance is maintained then the code gets a little
trickier, but there balances only need to be adjusted up to a pivot node. 9. Heaps

In addition, AVL trees can be implemented with recursive or iterative insert and delete 10. Balanced Binary Search Trees
methods. Both are described in the text. 10.1. AVL Tree Implementations

10.1.1. Iteratively Implemented


10.1.1. Iteratively Implemented AVL Tree AVL Tree

You can download avltree.py to work on an iterative implementation of AVL Trees. 10.1.2. Recursively Implemented
AVL Tree
1
2 ''' 10.2. Splay Tree Implementations
3 File: avltree.py
10.2.1. Iteratively Implemented
4 Author: Steve Hubbard, and
Splay Tree
5 Date:
6 Description: This module provides the AVLNode and AVLTree classes. 10.2.2. Recursively Implemented
7 ''' Splay Tree
8 10.3. Figures from Text
9 from person import Person
11. B-Trees
10 from stack import Stack
11 12. Heuristic Search
12 class AVLNode:
13 def __init__(self, item, balance = 0):
self.item = item
SEARCH
14
15 self.left = None Go
16 self.right = None Enter search terms or a module, class or
17 self.balance = balance function name.
18
19 def __str__(self):

20 ''' This performs an inorder traversal of the tree rooted at self,


21 using recursion. Return the corresponding string.
22 '''
23 st = str(self.item) + ' ' + str(self.balance) + '\n'
24 if self.left != None:
25 st = str(self.left) + st # A recursive call: str(self.left)
26 if self.right != None:

27 st = st + str(self.right) # Another recursive call


28 return st

29
30 def rotateLeft(self):
31 ''' Perform a left rotation of the subtree rooted at the
32 receiver. Answer the root node of the new subtree.
33 '''
34 child = self.right

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 1/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
35 if (child == None):
36 print( 'Error! No right child in rotateLeft.' )
37 return None # redundant
38 else:
39 self.right = child.left
40 child.left = self
41 return child
42
43 def rotateRight(self):
44 ''' Perform a right rotation of the subtree rooted at the
45 receiver. Answer the root node of the new subtree.
46 '''
47 child = self.left
48 if (child == None):
49 print( 'Error! No left child in rotateRight.' )
50 return None # redundant
51 else:
52 self.left = child.right
53 child.right = self
54 return child
55
56 def rotateRightThenLeft(self):
57 '''Perform a double inside left rotation at the receiver. We
58 assume the receiver has a right child (the bad child), which has a left
59 child. We rotate right at the bad child then rotate left at the pivot
60 node, self. Answer the root node of the new subtree. We call this
61 case 3, subcase 2.
62 '''
63 pass
64
65 def rotateLeftThenRight(self):
66 '''Perform a double inside right rotation at the receiver. We
67 assume the receiver has a left child (the bad child) which has a right
68 child. We rotate left at the bad child, then rotate right at
69 the pivot, self. Answer the root node of the new subtree. We call this
70 case 3, subcase 2.
71 '''
72 pass
73
74 class AVLTree:
75 def __init__(self):
76 self.root = None
77 self.count = 0
78
79 def __str__(self):
80 st = 'There are ' + str(self.count) + ' nodes in the AVL tree.\n'
81 return st + str(self.root) # Using the string hook for AVL nodes
82
83 def insert(self, newItem):
84 ''' Add a new node with item newItem, if there is not a match in the
85 tree. Perform any rotations necessary to maintain the AVL tree,
86 including any needed updates to the balances of the nodes. Most of the
87 actual work is done by other methods.
88 '''
89 pass
90
91 def adjustBalances(self, theStack, pivot, newItem):
92 ''' We adjust the balances of all the nodes in theStack, up to and
93 including the pivot node, if any. Later rotations may cause
94 some of the balances to change.
95 '''
96 pass
97
98 def case1(self, theStack, pivot, newItem):
99 ''' There is no pivot node. Adjust the balances of all the nodes
100 in theStack.

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 2/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
101 '''
102 self.adjustBalances(theStack, pivot, newItem)
103
104 def case2(self, theStack, pivot, newItem):
105 ''' The pivot node exists. We have inserted a new node into the
106 subtree of the pivot of smaller height. Hence, we need to adjust
107 the balances of all the nodes in the stack up to and including
108 that of the pivot node. No rotations are needed.
109 '''
110 self.adjustBalances(theStack, pivot, newItem)
111
112 def case3(self, theStack, pivot, newItem):
113 ''' The pivot node exists. We have inserted a new node into the
114 larger height subtree of the pivot node. Hence rebalancing and
115 rotations are needed.
116 '''
117 self.adjustBalances(theStack, pivot, newItem)
118 # Lots more!!!!
119
120 def search(self, newItem):
121 ''' The AVL tree is not empty. We search for newItem. This method will
122 return a tuple: (pivot, theStack, parent, found).
123 In this tuple, if there is a pivot node, we return a reference to it
124 (or None). We create a stack of nodes along the search path -- theStack.
125 We indicate whether or not we found an item which matches newItem. We
126 also return a reference to the last node the search examined -- referred
127 to here as the parent. (Note that if we find an object, the parent is
128 reference to that matching node.) If there is no match, parent is a
129 reference to the node used to add a child in insert().
130 '''
131 pass
132
133
134 def main():
135 print("Our names are ")
136 print()
137 a = AVLNode(20, -1)
138 b = AVLNode( 30, -1)
139 c = AVLNode(-100)
140 d = AVLNode(290)
141 '''
142 print(a)
143 print(b)
144 '''
145 t = AVLTree()
146 t.root = b
147 b.left = a
148 a.left = c
149 b.right = d
150 t.count = 4
151 print(t)
152
153 a = AVLNode(50)
154 b = AVLNode(30)
155 c = AVLNode(40)
156 a.left = b
157 b.right = c
158 print("Testing rotateLeftThenRight()")
159 print(a.rotateLeftThenRight())
160
161 (pivot, theStack, parent, found) = t.search(-70)
162 print(pivot.item, parent.item, found)
163 print()
164 print("The items in the nodes of the stack are: ")
165 while not theStack.isEmpty():
166 current = theStack.pop()

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 3/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
167 print(current.item)
168 print()
169
170 (pivot, theStack, parent, found) = t.search(25)
171 print(pivot.item, parent.item, found)
172
173 (pivot, theStack, parent, found) = t.search(-100)
174 print(pivot.item, parent.item, found)
175
176 if __name__ == '__main__': main()
177 ''' The output from main():
178 [evaluate avltree.py]
179 Our names are
180 There are 4 nodes in the AVL tree.
181 -100 0
182 20 -1
183 30 -1
184 290 0
185
186 Testing rotateLeftThenRight()
187 30 0
188 40 0
189 50 0
190
191 20 -100 False
192
193 The items in the nodes of the stack are:
194 -100
195 20
196 30
197
198 20 20 False
199 20 -100 True
'''

10.1.2. Recursively Implemented AVL Tree


AVL trees may also be implemented recursively meaning that the insert and delete methods
can be written recursively. The outline of this implementation can be seen in the text. It is
relatively short and is not provided for download.

10.2. Splay Tree Implementations

Splay trees do not maintain the balance or height. Instead they rely on rotations that always
rotate a inserted or accessed element to the root of the tree. In doing this they maintain a
balance in the tree, often exploiting spatial locality. Again, splay trees may be implemented
recursively or iteratively.

10.2.1. Iteratively Implemented Splay Tree


You can download splaytree.py to work on an iterative implementation of splay trees. To run this
program you will need to download stack.py module and you’ll need to download person.py
module.
1
2 '''
3 File: splaytree.py
4 Author(s): Steve Hubbard and
5 Date: 9/17/13
6 Description: This module implements the SplayTree class and the
7 SplayNode class. The classes use bottom up splaying rather than
8 top down splaying. We do not allow duplicate objects in the tree.
9 '''
10
11 from person import Person

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 4/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
12 from copy import deepcopy
13 from stack import Stack
14
15 class SplayNode:
16 ''' This module implements the SplayNode class. This
17 class in turn is used by the SplayTree class. The classes
18 use bottom up splaying rather than top down splaying. We
19 do not allow duplicate objects in the tree.
20 '''
21
22 def __init__(self, item, left = None, right = None):
23 self.left = left
24 self.item = item
25 self.right = right
26
27 def __str__(self):
28 st = '('
29 if (self.left == None):
30 st += '*'
31 else:
32 st += str(self.left) # recursion
33 st += str(self.item)
34 if (self.right == None):
35 st += '*'
36 else:
37 st += str(self.right) # recursion
38 st += ')'
39 return st
40
41 def inorder(self):
42 ''' Perform an inorder traversal of the subtree rooted at
43 the receiver. Print each item in this subtree during
44 the traversal. This is done with recursion.
45 '''
46 pass
47
48 def insertInNode(self, anItem):
49 ''' Try to insert a copy of anItem into the bottom up splay
50 tree rooted at the receiver. If anItem is already in the tree,
51 do not insert an extra copy. In any case, splay the new node,
52 or the last node on the search path, to the root. The method
53 will answer a tuple. The first element is True or False
54 according to whether a new element was added or not. The
55 second element is the new root node.
56 '''
57 pass
58
59 def rotateLeft(self):
60 ''' Perform a left rotation of the subtree rooted at the
61 receiver. Answer the root node of the new subtree.
62 '''
63 child = self.right
64 if (child == None):
65 print( 'Error! No right child in rotateLeft. ' )
66 return None # redundant
67 else:
68 self.right = child.left
69 child.left = self
70 return child
71
72 def splayToRoot(self, stack):
73 ''' Perform a bottom up splay beginning at the node at the
74 top of the stack. Answer the root of the new tree.
75 '''
76 pass
77

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 5/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
78 ''' Many more methods! '''
79
80
81 class SplayTree:
82
83 def __init__(self):
84 self.size = 0
85 self.root = None
86
87 def __str__(self):
88 if self.root != None:
89 return str(self.root)
90 else:
91 return ""
92
93 def delete(self, anItem):
94 ''' Atempt to find a match (==) for anItem in the receiver.
95 If found, splay the corresponding node to the root and answer
96 the item of the node. If not found, splay the last node on
97 the search path to the root. In this case, answer None. If
98 found, we remove the node and make the largest element of the
99 new left subtree (from the splaying of the node to the root
100 position) the new root node of the tree. Of course finding
101 the largest element uses a splaying on that left subtree.
102 If there is no left subtree, the right subtree becomes the
103 root. This may leave us with an empty tree. If found,
104 decrement the size of the tree and answer the item deleted.
105 If not found, answer None.
106 '''
107 pass
108
109 def findMax(self):
110 ''' Find the largest element in the splay tree. Splay that
111 element to the root. Answer a deep copy of the element.
112 If the tree is empty, answer None.
113 '''
114 pass
115
116 def findMin(self):
117 ''' Find the smallest element in the splay tree. Splay that
118 element to the root. Answer a deep copy of the element. If
119 the tree is empty, answer None.
120 '''
121 if (self.root == None):
122 return None
123 self.root = self.root.findMin()
124 return deepcopy(self.root.getItem())
125
126 def getSize(self):
127 return self.size
128
129 def inorder(self):
130 ''' Print the contents of the receiver, in inorder.
131 Print one item per line.
132 '''
133 if self.root != None:
134 self.root.inorder()
135
136 def insert(self, anItem):
137 ''' Insert a deep copy of anItem into the bottom up splay tree.
138 If anItem is already present in the tree, do not insert a new
139 copy of anItem. If anItem is added, increment the size of
140 the receiver. In either case, we splay from
141 the last node. If anItem was added, answer anItem. If not,
142 answer None.
143 '''

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 6/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
144 pass
145
146 def retrieve(self, anItem):
147 pass
148
149 def update(self, anItem):
150 pass
151
152
153 def main():
154
155 print('My name is ')
156 print('Test the SplayNode class: ')
157
158 a = SplayNode(20, SplayNode(10), SplayNode(25))
159 b = SplayNode(40, SplayNode(35), SplayNode(45))
160 c = SplayNode(30, a, b)
161 x = c.rotateLeft()
162 print( x )
163 print( str(x) == '((((*10*)20(*25*))30(*35*))40(*45*))' )
164 print( '' )
165
166 a = SplayNode(20, SplayNode(10), SplayNode(25))
167 b = SplayNode(40, SplayNode(35), SplayNode(45))
168 c = SplayNode(30, a, b)
169 x = c.rotateRight()
170 print( x )
171 print( str(x) == '((*10*)20((*25*)30((*35*)40(*45*))))' )
172 print( '' )
173
174 a = SplayNode(20, SplayNode(10), SplayNode(25))
175 b = SplayNode(40, SplayNode(35), SplayNode(45))
176 c = SplayNode(30, a, b)
177 d = SplayNode(60, SplayNode(55), SplayNode(65))
178 e = SplayNode(90, SplayNode(80), SplayNode(100))
179 f = SplayNode(70, d, e)
180 root = SplayNode(50, c, f)
181 print( root )
182 print( '' )
183
184 a = SplayNode(20, SplayNode(10), SplayNode(25))
185 b = SplayNode(40, SplayNode(35), SplayNode(45))
186 c = SplayNode(30, a, b)
187 d = SplayNode(60, SplayNode(55), SplayNode(65))
188 e = SplayNode(90, SplayNode(80), SplayNode(100))
189 f = SplayNode(70, d, e)
190 root = SplayNode(50, c, f)
191 x = root.rotateRightThenLeft()
192 print( x )
193 print( str(x) == \
194 '(((((*10*)20(*25*))30((*35*)40(*45*)))50(*55*))60((*65*)70((*80*)90(*100*))))' )
195 print( '' )
196
197 a = SplayNode(20, SplayNode(10), SplayNode(25))
198 b = SplayNode(40, SplayNode(35), SplayNode(45))
199 c = SplayNode(30, a, b)
200 d = SplayNode(60, SplayNode(55), SplayNode(65))
201 e = SplayNode(90, SplayNode(80), SplayNode(100))
202 f = SplayNode(70, d, e)
203 root = SplayNode(50, c, f)
204 x = root.rotateLeftThenRight()
205 print( x )
206 print( str(x) == \
207 '((((*10*)20(*25*))30(*35*))40((*45*)50(((*55*)60(*65*))70((*80*)90(*100*)))))' )
208 print( '' )
209

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 7/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
210 a = SplayNode(20, SplayNode(10), SplayNode(25))
211 b = SplayNode(40, SplayNode(35), SplayNode(45))
212 c = SplayNode(30, a, b)
213 d = SplayNode(60, SplayNode(55), SplayNode(65))
214 e = SplayNode(90, SplayNode(80), SplayNode(100))
215 f = SplayNode(70, d, e)
216 root = SplayNode(50, c, f)
217 x = root.doubleRotateLeft()
218 print( x )
219 print( str(x) == \
220 '((((((*10*)20(*25*))30((*35*)40(*45*)))50((*55*)60(*65*)))70(*80*))90(*100*))' )
221 print( '' )
222
223 a = SplayNode(20, SplayNode(10), SplayNode(25))
224 b = SplayNode(40, SplayNode(35), SplayNode(45))
225 c = SplayNode(30, a, b)
226 d = SplayNode(60, SplayNode(55), SplayNode(65))
227 e = SplayNode(90, SplayNode(80), SplayNode(100))
228 f = SplayNode(70, d, e)
229 root = SplayNode(50, c, f)
230 x = root.doubleRotateRight()
231 print( x )
232 print( str(x) == \
233 '((*10*)20((*25*)30(((*35*)40(*45*))50(((*55*)60(*65*))70((*80*)90(*100*))))))' )
234 print( '' )
235
236 a = SplayNode(20, SplayNode(10), SplayNode(25))
237 b = SplayNode(40, SplayNode(35), SplayNode(45))
238 c = SplayNode(30, a, b)
239 d = SplayNode(60, SplayNode(55), SplayNode(65))
240 e = SplayNode(90, SplayNode(80), SplayNode(100))
241 f = SplayNode(70, d, e)
242 root = SplayNode(50, c, f)
243 x = root.find(35)
244 print( x )
245 print( str(x) == \
246 '((((*10*)20(*25*))30*)35((*40(*45*))50(((*55*)60(*65*))70((*80*)90(*100*)))))')
247
248 print('Test the SplayTree class: ')
249 t = SplayTree()
250 t.insert(1)
251 t.insert(2)
252 t.insert(3)
253 t.insert(4)
254 t.insert(5)
255 t.insert(6)
256 t.insert(7)
257 t.retrieve(1)
258 print( str(t) == '(*1(((*2(*3*))4(*5*))6(*7*)))')
259 print( 'The size of the tree is ' + str(t.getSize()) )
260
261 t = SplayTree()
262 t.insert(1)
263 t.insert(2)
264 t.insert(3)
265 t.insert(4)
266 t.insert(5)
267 t.insert(6)
268 t.insert(7)
269 t.findMin()
270 print( str(t) == '(*1(((*2(*3*))4(*5*))6(*7*)))')
271
272 t = SplayTree()
273 t.insert(1)
274 t.insert(2)
275 t.insert(3)

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 8/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
276 t.insert(4)
277 t.insert(5)
278 t.insert(6)
279 t.insert(7)
280 t.retrieve(1)
281 t.delete(3)
282 print( str(t) == '((*1*)2((*4(*5*))6(*7*)))' )
283
284 t = SplayTree()
285 t.insert(1)
286 t.insert(2)
287 t.insert(3)
288 t.insert(4)
289 t.insert(5)
290 t.insert(6)
291 t.insert(7)
292 t.retrieve(1)
293 t.delete(3)
294 t.findMax()
295 print( str(t) == '((((*1*)2(*4(*5*)))6*)7*)')
296
297 t = SplayTree()
298 t.insert(Person('Joe', 25))
299 t.insert(Person('Jill',35))
300 t.insert(Person('Jon',15))
301 t.insert(Person('Jack',25))
302 t.insert(Person('John',30))
303 t.insert(Person('Jud',95))
304 t.insert(Person('Joey',27))
305 st = str(t) + '\n'
306 t.update(Person('James', 25))
307 st += str(t) + '\n'
308 x = t.retrieve(Person('',15))
309 st += str(x) + '\n'
310 st += str(t) + '\n'
311 x = t.delete(Person('', 35))
312 st += str(x) + '\n'
313 st += str(t) + '\n'
314 x = t.findMax()
315 st += str(x) + '\n'
316 st += str(t) + '\n'
317 print( t )
318
319 print( 'The size of the tree is ' + str(t.getSize()) )
320
321 t = SplayTree()
322 t.insert(1)
323 t.insert(2)
324 t.insert(3)
325 t.insert(4)
326 t.insert(5)
327 t.insert(6)
328 t.insert(7)
329 t.insert(3.5)
330 print( str(t) == '((((*1*)2*)3*)3.5(((*4*)5(*6*))7*))' )
331
332 t = SplayTree()
333 t.insert(1)
334 t.insert(2)
335 t.insert(3)
336 t.insert(4)
337 t.insert(5)
338 t.insert(6)
339 t.insert(7)
340 t.insert(3.5)
341 t.delete(3.5)

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 9/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
342 print( str(t) == '(((*1*)2*)3(((*4*)5(*6*))7*))')
343 print( 'The size of the tree is ' + str(t.getSize()) )
344
345
346 t = SplayTree()
347 t.insert(3)
348 t.insert(2)
349 t.insert(1)
350 t.delete(1)
351 print( 'The size of the tree is ' + str(t.getSize()) )
352
353 t = SplayTree()
354 t.insert(Person('Joe', 25))
355 t.insert(Person('Jill',35))
356 t.insert(Person('Jon',15))
357 t.insert(Person('Jack',25))
358 t.insert(Person('John',30))
359 t.insert(Person('Jud',95))
360 t.insert(Person('Joey',27))
361 t.inorder()
362
363 if __name__ == '__main__': main()
364
365 ''' Output, from splaytree.py, wrapped around!
366 [evaluate splaytree.py]
367 My name is
368 Test the SplayNode class:
369 ((((*10*)20(*25*))30(*35*))40(*45*))
370 True
371
372 ((*10*)20((*25*)30((*35*)40(*45*))))
373 True
374
375 ((((*10*)20(*25*))30((*35*)40(*45*)))50(((*55*)60(*65*))70((*80*)90(*100*))))
376
377 (((((*10*)20(*25*))30((*35*)40(*45*)))50(*55*))60((*65*)70((*80*)90(*100*))))
378 True
379
380 ((((*10*)20(*25*))30(*35*))40((*45*)50(((*55*)60(*65*))70((*80*)90(*100*)))))
381 True
382
383 ((((((*10*)20(*25*))30((*35*)40(*45*)))50((*55*)60(*65*)))70(*80*))90(*100*))
384 True
385
386 ((*10*)20((*25*)30(((*35*)40(*45*))50(((*55*)60(*65*))70((*80*)90(*100*))))))
387 True
388
389 ((((*10*)20(*25*))30*)35((*40(*45*))50(((*55*)60(*65*))70((*80*)90(*100*)))))
390 True
391 Test the SplayTree class:
392 True
393 The size of the tree is 7
394 True
395 True
396 True
397 ((((*Name: Jon Id: 15 (*Name: James Id: 25 *))Name: Joey Id: 27 *)
398 Name: John Id: 30 *)Name: Jud Id: 95 *)
399 The size of the tree is 5
400 True
401 True
402 The size of the tree is 7
403 The size of the tree is 2
404 Name: Jon Id: 15
405 Name: Joe Id: 25
406 Name: Joey Id: 27
407 Name: John Id: 30

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 10/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
408 Name: Jill Id: 35
409 Name: Jud Id: 95
410
411 '''
412
413
414

10.2.2. Recursively Implemented Splay Tree


A recursive implementation of splay trees relies on keeping track of the left or right double
rotations as the recursive insert or lookup returns up the tree. To accomplish this you must
call a rotate function. Calling rotate[“RL”](pivot) would call the rotate right then left double
rotation. The rotate variable is a dictionary (i.e. hash table) in the code provided here.
You can download splay.py file to begin working on the recursive splay tree implementation.

1
2 '''
3 File: splay.py
4 Author: Kent D. Lee
5 Date: 8/21/2014
6 Description: This module implements the SplayTree class. This
7 class uses the SplayNode class. The classes
8 use bottom up splaying rather than top down splaying. We
9 do not allow duplicate objects in the tree.
10
11 Delete is not implemented in this file currently. Test code
12 should be added to thoroughly test insert, lookup, and delete.
13 Recall that looking up a value rotates it to the root. Deleting
14 an item rotates its parent to the root.
15 '''
16
17 def rotateLeft(pivot):
18 pass

19
20 def rotateRight(pivot):
21 pass

22
23 def rotateRL(pivot):
24 pass

25
26 def rotateLR(pivot):
27 pass
28
29 def rotateRR(pivot):
30 pass

31
32 def rotateLL(pivot):
33 pass
34
35 rotate = {}
36 rotate["RL"] = rotateRL
37 rotate["LR"] = rotateLR
38 rotate["RR"] = rotateRR
39 rotate["LL"] = rotateLL
40
41 singleRotate = {}
42 singleRotate["R"] = rotateRight
43 singleRotate["L"] = rotateLeft
44
45 class SplayTree:
46
47 class SplayNode:

48 def __init__(self, item, left=None, right=None):


49 self.item = item

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 11/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
50 self.left = left
51 self.right = right
52
53 def __str__(self):
54 st = '('
55 if (self.left == None):
56 st += '*'
57 else:
58 st += str(self.left)
59 st += str(self.item)
60 if (self.right == None):
61 st += '*'
62 else:
63 st += str(self.right)
64 st += ')'
65 return st
66
67 def __init__(self):
68 self.root = None
69 self.rString = ""
70
71
72 # Pass searching = True if just searching and not
73 # really inserting. If the item is found, true is
74 # returned. If the item is not found, an exception
75 # containing false is raised.
76
77 def insert(self,item,searching=False):
78
79 def __insert(root,item):
80 ''' return the new root after inserting
81 item into the tree currently rooted at
82 root. If searching for the value and not
83 inserting, then raise Exception(False) if
84 the item is not found.
85 '''
86
87 return root
88
89 self.found = False
90
91 self.root = __insert(self.root,item)
92
93 # Handle any single rotation that must
94 # be done after inserting the value.
95 if self.rString in singleRotate:
96 self.root = singleRotate[self.rString](self.root)
97
98 self.rString = ""
99
100 return self.found
101
102 def lookup(self,item):
103
104 try:
105 return self.insert(item,True)
106 except Exception as inst:
107 if inst.args[0] == False:
108 return False
109
110 raise Exception(inst)
111
112 def __str__(self):
113 if self.root != None:
114 return str(self.root)
115 else:

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 12/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python
116 return ""
117
118 def main():
119 # This should print the following.
120 #(*20*)
121 #((*20*)30*)
122 #(*5(*20(*30*)))
123 #((*5*)8(*20(*30*)))
124 #(((*5*)8((*20*)30*))42*)
125 #(((*5*)8*)15((*20(*30*))42*))
126 #(((*5*)8*)10(*15((*20(*30*))42*)))
127 t = SplayTree2()
128 t.insert(20)
129 print(str(t))
130 t.insert(30)
131 print(str(t))
132 t.insert(5)
133 print(str(t))
134 t.insert(8)
135 print(str(t))
136 t.insert(42)
137 print(str(t))
138 t.insert(15)
139 print(str(t))
140 t.insert(10)
141 print(str(t))
142
143
if __name__ == '__main__': main()

10.3. Figures from Text

Fig. 1: AVL Tree Case 1 - No Pivot Node

Fig. 2: AVL Tree Case 2 - No Rotate

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 13/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python

Fig. 3: AVL Tree Case 3A - Single Rotation

Fig. 4: AVL Tree Case 3B - Double Rotation

Fig. 5: AVL Tree Case 3B Step 1 Rotate Toward

Fig. 6: AVL Tree Case 3B Step 2 Rotate Away

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 14/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python

Fig. 7: AVL Tree Case 3A Right Rotation

Fig. 8: AVL Tree Case 3A Left Rotation

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 15/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python

Fig. 9: AVL Tree Case 3B Steps 1 and 2

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 16/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python

Fig. 10: Splay Tree Double-Right Rotate

Fig. 11: Splay Tree Double-Left Rotate

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 17/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python

Fig. 12: Splay Tree Right-Left Rotate

Fig. 13: Splay Tree Left-Right Rotate

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 18/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python

Fig. 14: Splay Tree Example

Fig. 15: Average Insert/Lookup Time

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 19/20
7/16/2019 10. Balanced Binary Search Trees — Data Structures and Algorithms with Python

PREVIOUS | NEXT | INDEX


SHOW SOURCE
© Copyright 2014, Kent D. Lee and Steve Hubbard. Created using Sphinx 1.2.2

knuth.luther.edu/~leekent/CS2Plus/chap9/chap9.html 20/20

Anda mungkin juga menyukai