红黑树的Python实现

想用红黑树,怎么搜都搜不到现成的Python实现。干脆自己写一个。

算法的结构按照Sedgewick的《算法(4th)》一书第三章写成,略有改动。

完整的API实现,也用了一些测试case,暂时没发现问题。

这玩意就是好用,谁用谁知道。

废话不多说直接上代码。

#注意事项: 重载RBT.Node.reduce(self,new_val)来实现 append()方法中对已存在主键对应值的自定义合并操作。默认为调用list.extend()方法。

  1 #!/usr/bin/env python
  2 #coding: gbk
  3
  4 ########################################################################
  5 #Author: Feng Ruohang
  6 #Create: 2014/10/06 11:38
  7 #Digest: Provide a common data struct: Red Black Tree
  8 ########################################################################
  9
 10 class RBT(object):
 11     class Node(object):
 12         ‘‘‘
 13         Node used in RBTree
 14         ‘‘‘
 15         def __init__(self,key,value=None,color=False,N=1):
 16             self.key = key
 17             self.val = value
 18             self.color = color   #False for Black, True for Red
 19             self.N = N           #Total numbers of nodes in this subtree
 20             self.left = None
 21             self.right = None
 22
 23         def __cmp__(l,r):
 24             return cmp(l.key,r.key)
 25
 26         def __eq__(l,r):
 27             return True if l.key == r.key else False
 28
 29         def __add__(l,r):
 30             l.value + r.value
 31
 32         def reduce(self,new_val):
 33             self.val.extend(new_val)
 34
 35     def __init__(self):
 36         self.root = None
 37
 38     #====================APIs====================#
 39     #=====Basic API
 40
 41     def get(self,key):
 42         return  self.__get(self.root,key)
 43
 44     def put(self,key,val):
 45         self.root = self.__put(self.root,key,val)
 46         self.root.color = False
 47
 48     def append(self,key,val):
 49         self.root = self.__append(self.root,key,val)
 50         self.root.color = False
 51
 52     def delete(self,key):
 53         if not self.contains(key):
 54             raise LookupError(‘No such keys in rbtree. Fail to Delete‘)
 55         if self.__is_black(self.root.left) and self.__is_black(self.root.right):
 56             self.root.color = True
 57         self.root = self.__delete(self.root,key)
 58         if not self.is_empty():
 59             self.root.color = False
 60
 61     def del_min(self):
 62         if self.is_empty():
 63             raise LookupError(‘Empty Red-Black Tree. Can\‘t delete min‘)
 64         if self.__is_black(self.root.left) and self.__is_black(self.root.right):
 65             self.root.color = True
 66         self.root = self.__del_min(self.root)
 67         if not self.is_empty(): self.root.color = False
 68
 69     def del_max(self):
 70         if self.is_empty():
 71             raise LookupError(‘Empty Red-Black Tree. Can\‘t delete max‘)
 72         if self.__is_black(self.root.left) and self.__is_black(self.root.right):
 73             self.root.color = True
 74         self.root = self.__del_max(self.root)
 75         if not self.is_empty(): self.root.color = False
 76
 77     def size(self):
 78         return self.__size(self.root)
 79
 80     def is_empty(self):
 81         return not self.root
 82
 83     def contains(self,key):
 84         return bool(self.get(key))
 85
 86     #=====Advance API
 87     def min(self):
 88         if self.is_empty():
 89             return None
 90         return self.__min(self.root).key
 91
 92     def max(self):
 93         if self.is_empty():
 94             return None
 95         return self.__max(self.root).key
 96
 97     def floor(self,key):
 98         x = self.__floor(self.root,key)
 99         if x:
100             return x.key,x.val
101         else:
102             return None,None
103
104     def ceil(self,key):
105         x = self.__ceil(self.root,key)
106         if x:
107             return x.key,x.val
108         else:
109             return None,None
110
111     def below(self,key):
112         index = self.index(key)
113         if not 0 <= index - 1 < self.size():
114             return None,None    #Return None if out of range
115         x = self.__select(self.root,index - 1)
116         return x.key,x.val
117
118     def above(self,key):
119         index = self.index(key)
120         if self.contains(key):
121             if not 0 <= index + 1 < self.size():
122                 return None,None    #Return None if out of range
123             else:
124                 x = self.__select(self.root,index+1)
125                 return x.key,x.val
126         else:#if key is not in tree. then select(i) is what we need
127             if not 0 <= index < self.size():
128                 return None,None    #Return None if out of range
129             else:
130                 x = self.__select(self.root,index)
131                 return x.key,x.val
132
133     def index(self,key):
134         return self.__index(self.root,key)
135
136     def keys(self):
137         ‘‘‘Return All Keys in the tree ‘‘‘
138         return self.range(self.min(),self.max())
139
140     def range(self,lo,hi):
141         ‘‘‘Take two keys. return keys between them‘‘‘
142         q = []
143         self.__range(self.root,q,lo,hi)
144         return q
145
146     def select(self,index):
147         ‘‘‘Given Index Return Corresponding key ‘‘‘
148         if not 0 <= index < self.size():
149             return None
150         return self.__select(self.root,index).key
151
152     def width(self,lo,hi):
153         ‘‘‘Return the numbers of keys between lo and hi ‘‘‘
154         if lo > hi:
155             return 0
156         if self.contains(hi):
157             return self.index(hi) - self.index(lo) + 1
158         else:
159             return self.index(hi) - self.index(lo)
160
161
162     #===============Private Method===============#
163     #=====Basic
164     def __get(self,x,key):
165         while x:
166             tag = cmp(key,x.key)
167             if tag < 0 : x = x.left
168             elif tag > 0 :x = x.right
169             else: return x.val
170
171     def __put(self,h,key,val):
172         if not h:
173             return self.Node(key,val,True,1)
174         tag = cmp(key,h.key)
175         if tag < 0:
176             h.left = self.__put(h.left,key,val)
177         elif tag > 0:
178             h.right = self.__put(h.right,key,val)
179         else:
180             h.val = val   #Update
181
182         if self.__is_black(h.left) and self.__is_red(h.right):
183             h = self.__rotate_left(h)
184         if self.__is_red(h.left) and self.__is_red(h.left.left):
185             h = self.__rotate_right(h)
186         if self.__is_red(h.left) and self.__is_red(h.right):
187             self.__flip_colors(h)
188         h.N = self.__size(h.left) + self.__size(h.right) + 1
189         return h
190
191     def __append(self,h,key,val):
192         if not h:
193             return self.Node(key,val,True,1)
194         tag = cmp(key,h.key)
195         if tag < 0:
196             h.left = self.__append(h.left,key,val)
197         elif tag > 0:
198             h.right = self.__append(h.right,key,val)
199         else:
200             h.reduce(val)   #append.
201
202         if self.__is_black(h.left) and self.__is_red(h.right):
203             h = self.__rotate_left(h)
204         if self.__is_red(h.left) and self.__is_red(h.left.left):
205             h = self.__rotate_right(h)
206         if self.__is_red(h.left) and self.__is_red(h.right):
207             self.__flip_colors(h)
208         h.N = self.__size(h.left) + self.__size(h.right) + 1
209         return h
210
211     def __del_min(self,h):
212         if not h.left: #if h is empty:return None
213             return None
214
215         if self.__is_black(h.left) and self.__is_black(h.left.left):
216             self.__move_red_left(h)
217         h.left = self.__del_min(h.left) #Del recursive
218         return self.__balance(h)
219
220     def __del_max(self,h):
221         if self.__is_red(h.left):
222             h = self.__rotate_right(h)
223         if not h.right:
224             return None
225         if self.__is_black(h.right) and self.__is_black(h.right.left):
226             h = self.__move_red_right(h)
227         h.right = self.__del_max(h.right)
228         return self.__balance(h)
229
230     def __delete(self,h,key):
231         if key < h.key:
232             if self.__is_black(h.left) and self.__is_black(h.left.left):
233                 h = self.__move_red_left(h)
234             h.left = self.__delete(h.left,key)
235         else:
236             if self.__is_red(h.left):
237                 h = self.__rotate_right(h)
238             if key == h.key and not h.right:
239                 return None
240             if self.__is_black(h.right) and self.__is_black(h.right.left):
241                 h = self.__move_red_right(h)
242             if key == h.key:#replace h with min of right subtree
243                 x = self.__min(h.right)
244                 h.key = x.key
245                 h.val = x.val
246                 h.right = self.__del_min(h.right)
247             else:
248                 h.right = self.__delete(h.right,key)
249         h = self.__balance(h)
250         return h
251
252     #=====Advance
253     def __min(self,h):
254         #Assume h is not null
255         if not h.left:
256             return h
257         else:
258             return self.__min(h.left)
259
260     def __max(self,h):
261         #Assume h is not null
262         if not h.right:
263             return h
264         else:
265             return self.__max(h.right)
266
267     def __floor(self,h,key):
268         ‘‘‘Find the NODE with key <= given key in the tree rooted at h ‘‘‘
269         if not h:
270             return None
271         tag = cmp(key,h.key)
272         if tag == 0:
273             return h
274         if tag < 0:
275             return self.__floor(h.left,key)
276         t = self.__floor(h.right,key)
277         if t:#if find in right tree
278             return t
279         else:#else return itself
280             return h
281
282     def __ceil(self,h,key):
283         ‘‘‘Find the NODE with key >= given key in the tree rooted at h ‘‘‘
284         if not h:
285             return None
286         tag = cmp(key,h.key)
287         if tag == 0:
288             return h
289         if tag > 0: # key is bigger
290             return self.__ceil(h.right,key)
291         t = self.__ceil(h.left,key)#key is lower.Try to find ceil left
292         if t:#if find in left tree
293             return t
294         else:#else return itself
295             return h
296
297     def __index(self,h,key):
298         if not h:
299             return 0
300         tag = cmp(key,h.key)
301         if tag < 0:
302             return self.__index(h.left,key)
303         elif tag > 0:   #Key is bigger
304             return self.__index(h.right,key) + 1 + self.__size(h.left)
305         else:   #Eq
306             return self.__size(h.left)
307
308     def __select(self,h,index):
309         ‘‘‘assert h. assert 0 <= index < size(tree) ‘‘‘
310         l_size = self.__size(h.left)
311         if l_size > index:
312             return self.__select(h.left,index)
313         elif l_size < index:
314             return self.__select(h.right,index - l_size - 1)
315         else:
316             return h
317
318     def __range(self,h,q,lo,hi):
319         if not h:
320             return
321         tag_lo = cmp(lo,h.key)
322         tag_hi = cmp(hi,h.key)
323         if tag_lo < 0:#lo key is lower than h.key
324             self.__range(h.left,q,lo,hi)
325         if tag_lo <= 0 and tag_hi >= 0:
326             q.append(h.key)
327         if tag_hi > 0 :# hi key is bigger than h.key
328             self.__range(h.right,q,lo,hi)
329
330
331     #===============Adjust Functions=============#
332     def __rotate_right(self,h):
333         x = h.left
334         h.left,x.right = x.right,h
335         x.color,x.N = h.color,h.N
336         h.color,h.N = True,self.__size(h.left) + self.__size(h.right) + 1
337         return x
338
339     def __rotate_left(self,h):
340         x = h.right
341         h.right,x.left = x.left,h
342         x.color,x.N = h.color,h.N
343         h.color,h.N = True,self.__size(h.left) + self.__size(h.right) + 1
344         return x
345
346     def __flip_colors(self,h):
347         h.color = not h.color
348         h.left.color = not h.left.color
349         h.right.color = not h.right.color
350
351     def __move_red_left(self,h):
352         self.__flip_colors(h)
353         if self.__is_red(h.right.left):
354             h = self.__rotate_left(h)
355         return h
356
357     def __move_red_right(self,h):
358         self.__flip_colors(h)
359         if self.__is_red(h.left.left):
360             h = self.__rotate_right(h)
361         return h
362
363     def __balance(self,h):
364         if self.__is_red(h.right):
365             h = self.__rotate_left(h)
366         if self.__is_red(h.left) and self.__is_red(h.left.left):
367             h = self.__rotate_right(h)
368         if self.__is_red(h.left) and self.__is_red(h.right):
369             self.__flip_colors(h)
370         h.N = self.__size(h.left) + self.__size(h.right) + 1
371         return h
372
373     #Class Method
374     @staticmethod
375     def __is_red(x):
376         return False if not x else x.color
377
378     @staticmethod
379     def __is_black(x):
380         return True  if not x else not x.color
381
382     @staticmethod
383     def __size(x):
384         return 0 if not x else x.N
385
386
387 def RBT_testing():
388     ‘‘‘API Examples ‘‘‘
389     t = RBT()
390     test_data = "SEARCHXMPL"
391
392     print ‘=====testing is_empty()\nBefore Insertion‘
393     print t.is_empty()
394
395     for letter in test_data:
396         t.put(letter,[ord(letter)])
397         print "Test Inserting:%s, tree size is %d" % (letter,t.size())
398     print "After insertion it return:"
399     print t.is_empty()
400     print  "====test is_empty complete\n"
401
402
403     print "=====Tesing Get method:"
404     print "get ‘s‘ is "
405     print t.get(‘S‘)
406     print "get ‘H‘ is "
407     print t.get(‘H‘)
408
409     print ‘==Trying get null key: get "F" is‘
410     print t.get(‘F‘)
411     print "=====Testing Get method end\n\n"
412
413     print "=====Testing ceil and floor"
414     print "Ceil(‘L‘)"
415     print t.ceil(‘L‘)
416     print "Ceil(‘F‘) *F is not in tree"
417     print t.ceil(‘F‘)
418
419     print "Floor(‘L‘)"
420     print t.ceil(‘L‘)
421     print "Floor(‘F‘)"
422     print t.ceil(‘F‘)
423
424     print ‘======test append method‘
425     print ‘Orient key e is correspond with‘
426     print t.get(‘E‘)
427     t.append(‘E‘,[4])
428     print ‘==After append‘
429     print t.get(‘E‘)
430     print "=====Testing Append method end\n\n"
431
432     print "=====Testing index()"
433     print "index(E)"
434     print t.index(‘E‘)
435     print "index(L),select(4)"
436     print t.index(‘L‘),t.select(4)
437     print "index(‘M‘),select(5)"
438     print t.index(‘M‘),t.select(5)
439     print "index a key not in tree:\n index(‘N‘),select(6)"
440     print t.index(‘N‘),t.select(6)
441     print "index(‘P‘)"
442     print t.index(‘P‘)
443
444
445     print "=====Testing select"
446     print "select(3) = "
447     print t.select(3)
448     print "select and index end...\n\n"
449
450     print "====Tesing Min and Max"
451     print "min key is:"
452     print t.min()
453     print "max key is"
454     print t.max()
455
456     print "==How much between min and max:"
457     print t.width(t.min(),t.max())
458     print "keys between min and max:"
459     print t.keys()
460     print "keys in ‘E‘ and ‘M‘ "
461     print t.range(‘E‘,‘M‘)
462
463
464     print "try to delete min_key:"
465     print "But we could try contains(‘A‘) first"
466     print t.contains(‘A‘)
467     t.del_min()
468     print "After deletion t.contains(‘A‘) is "
469     print t.contains(‘A‘)
470
471     print t.min()
472     print "try to kill one more min key:"
473     t.del_min()
474     print t.min()
475     print "try to delete max_key,New Max key is :"
476     t.del_max()
477     print t.max()
478     print "=====Tesing Min and Max complete\n\n"
479
480
481
482     print ‘=====Deleting Test‘
483     print t.size()
484     t.delete(‘H‘)
485     print t.size()
486
487     print ‘Delete a non-exists key:‘
488     try:
489         t.delete(‘F‘)
490     except:
491         print "*Look up error occur*"
492
493     print "=====Testing Delete method complete"
494
495 def test_basic_api():
496     print "==========Testing Basic API=========="
497     t = RBT()
498     print "Test Data: FENGDIJKABCLM"
499     test_data = "FENGDIJKABCLM" #from A-N,without H
500
501     #=====put()
502     print "==========put() test begin!=========="
503     for letter in test_data:
504         t.put(letter,[ord(letter)]) #Value is [ascii order of letter]
505         print "put(%s); Now tree size is %d"%(letter,t.size())
506     print ‘Final tree size is %d‘%t.size()
507     print "==========put() test complete!==========\n"
508
509     #=====get()
510     print "==========get() test begin!=========="
511     print "get(‘F‘):\t%s"%repr(t.get(‘F‘))
512     print "get(‘A‘):\t%s"%repr(t.get(‘A‘))
513     print "get a non-exist key Z: get(‘Z‘):\t%s"%repr(t.get(‘Z‘))
514     print "==========get() test complete!==========\n"
515
516     #=====append()
517     print "=====append() test begin!=========="
518     print "First append to a exist key:[F]"
519     print "Before Append:get(‘F‘):\t%s"%repr(t.get(‘F‘))
520     print "append(‘F‘,[3,‘haha‘]):\t%s"%repr(t.append(‘F‘,[3,‘haha‘]))
521     print "After Append:get(‘F‘):\t%s\n"%repr(t.get(‘F‘))
522     print "Second append to a non-exist key:[O]"
523     print "Before Append:get(‘O‘):\t%s"%repr(t.get(‘O‘))
524     print "append a non-exist key O: append(‘O‘,[‘value of O‘]):\t%s"%repr(t.append(‘O‘,[‘value of O‘]))
525     print "After Append:get(‘O‘):\t%s\n"%repr(t.get(‘O‘))
526     print "==========append() test complete!==========\n"
527
528     #=====delete()
529     print "==========delete() test begin!=========="
530     test_data2 = [x for x in test_data]
531     test_data2.reverse()
532     for letter in test_data2:
533         t.delete(letter)
534         print "delete(%s); Now tree size is %d"%(letter,t.size())
535     print ‘Final tree size is %d‘%t.size()
536     print "==========delete() test complete!==========\n"
537
538     print "==========Basic API Test Complete==========\n\n"
539
540 def test_advance_api():
541     print "==========Testing min max floor ceil above below =========="
542     t = RBT()
543     print "Test Data: FENGDIJKABCLM"
544     test_data = "FENGDIJKABCLM" #from A-N,without H
545     for letter in test_data:
546         t.put(letter,[ord(letter)]) #Value is [ascii order of letter]
547
548     #=====min() and del_min()
549     print "==========min() and del_min() test begin!=========="
550     print "Original min():\t%s"%repr(t.min())
551     print "run del_min()"
552     t.del_min()
553     print "After del_min:min()\t%s"%repr(t.min())
554
555     print "run del_min() again"
556     t.del_min()
557     print "After del_min run again:min()\t%s"%repr(t.min())
558
559     print "=====max() and del_max() test begin!"
560     print "Original max():\t%s"%repr(t.max())
561     print "run del_max()"
562     t.del_max()
563     print "After del_max:max()\t%s"%repr(t.max())
564
565     print "run del_max() again"
566     t.del_max()
567     print "After del_max run again:max()\t%s"%repr(t.max())
568     print "==========min() max() del_min() del_max() test complete!==========\n"
569
570 def test_int_api():
571     #======ceil floor above below
572     print "==========Testing ceil floor above below =========="
573     t = RBT()
574     print "Test Data: FENGDIJKABCLM - [AHN] = FEGDIJKBCLM"
575     test_data = "FEGDIJKBCLM" #from A-N, Del A H N
576
577     for letter in test_data:
578         t.put(letter,[ord(letter)]) #Value is [ascii order of letter]
579     print "Node\tceil\t\tfloor\t\tabove\t\tbelow"
580     for P in [‘A‘,‘B‘,‘C‘,‘G‘,‘H‘,‘I‘,‘L‘,‘M‘,‘N‘]:
581         print "%s\t%s\t%s\t%s\t%s"%(P,t.ceil(P),t.floor(P),t.above(P),t.below(P))
582
583 if __name__ == ‘__main__‘:
584     test_basic_api()
585     test_advance_api()
586     test_int_api()

查找操作的数据结构不断进化,才有了红黑树:从链表到二叉平衡树,再到2-3树,最后到红黑树。

红黑树本质上是用二叉平衡树的形式来模拟2-3树的功能

《算法导论》也好,其他什么乱七八糟算法书博客也罢,讲红黑树都没讲到本质。

Sedgewick的《算法(4th)》这本书就很不错:起码他告诉你红黑树是怎么来的。

仔细理解2-3树与红黑树的相同之处,才能对那些乱七八糟的插入删除调整操作有直观的认识。

时间: 2024-08-28 20:29:59

红黑树的Python实现的相关文章

算法导论 第十三章 红黑树(python)-1插入

红黑树是上一章二叉搜索树的改进,实现一种平衡 ,保证不会出现二叉树变链表的情况,基本动态集合操作的时间复杂度为O(lgn) 实际用途:c++stl中的set,map是用他实现的 红黑树的性质: 1.每个结点或是红色的,或是黑色的 2.跟结点是黑色的 3.每个叶结点(NIL)是黑色 4.如果一个结点是红色的,则它的两个结点都是黑色的 5.对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同的数目的黑色结点(数目被称为黑高bh(x)) 如下图: (T.nil 哨兵后面被忽略 None) 红

Red-Black Tree 红黑树

如果viewer对Red-Black Tree先前没有任何了解,可以看看先搞定AVL树,因为AVL树比红黑树要简单的多 涉及同样的rotate技巧,搞懂了AVL树再和红黑大战三百回合绝对轻松的多. (我见过讲AVL最好的教程就是 Mark Allen Weiss 写的<数据结构与算法分析 C语言描述>里面讲AVL树的部分) AVL树的C语言实现: http://blog.csdn.net/cinmyheart/article/details/20527037 Here we go ~ 笔记贴-

B树、B+树、红黑树、AVL树比较

B树是为了提高磁盘或外部存储设备查找效率而产生的一种多路平衡查找树. B+树为B树的变形结构,用于大多数数据库或文件系统的存储而设计. B树相对于红黑树的区别 在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况.为什么会出现这样的情况,我们知道要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写.磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读

红黑树之删除节点

红黑树之删除节点 上一篇文章中讲了如何向红黑树中添加节点,也顺便创建了一棵红黑树.今天写写怎样从红黑树中删除节点. 相比于添加节点,删除节点要复杂的多.不过我们慢慢梳理,还是能够弄明白的. 回顾一下红黑树的性质 红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色.在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求: 节点是红色或黑色. 根节点是黑色. 每个叶节点(这里的叶节点是指NULL节点,在<算法导论>中这个节点叫哨兵节点,除了颜色属性外,其他属性值都为任

数据结构与算法-红黑树

前言 红黑树是工程中最常用到的一种自平衡二叉排序树,其和AVL树类似,都是在进行插入.删除时通过一定的调整操作来维持相对稳定的树高,从而获得较好的查询性能. 性质 1. 节点是红色或黑色. 2. 根节点是黑色. 3 每个叶节点(null节点)是黑色的. 4 每个红色节点的两个子节点都是黑色.(从每个叶子到根的所有路径上不能有两个连续的红色节点) 5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点. 维护红黑树形状(树高)的,主要就是4.5两条性质,性质4决定了最长的路径莫过于红黑间隔

数据结构学习笔记-排序/队/栈/链/堆/查找树/红黑树

排序: 插入排序:每次从剩余数据中选取一个最小的,插入已经排序完成的序列中 合并排序:将数据分成左右两组分别排序,然后合并,对每组数据的排序递归处理. 冒泡排序:重复交换两个相邻元素,从a[1]开始向a[0]方向冒泡,然后a[2]...当a[i]无法继续往前挤的时候说明前面的更小了,而且越往前越小(挤得越往前) 堆排序:构造最大堆,每次取走根结点(自然是最大的),再调用MAX-HEAPIFY算法(见后文的堆)恢复最大堆的性质,重复取走根结点 快速排序(对A[r]-A[n]进行排序): 1.从序列

红黑树与AVL(平衡二叉树)的区别

关于红黑树和AVL树,来自网络: 1 好处 及 用途 红黑树 并不追求"完全平衡 "--它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能. 红黑树能够以 O(log2  n)  的时间复杂度进行搜索.插入.删除操作.此外,由于它的设计,任何不平衡都会在三次旋转之内解决.当然,还有一些更好的,但实现起来更复杂的数据结构 能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较"便宜"的解决方案.红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高

数据结构-红黑树

转自:http://dongxicheng.org/structure/red-black-tree/ 1. 简介 红黑树是一种自平衡二叉查找树.它的统计性能要好于平衡二叉树(AVL树),因此,红黑树在很多地方都有应用.在C++ STL中,很多部分(目前包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持).它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它

红黑树

弄了很久,学习过程中觉得很难,但学完了,其实感觉也就那样,就是情况多了些. 首先是插入,插入的时候其实也就3种情况,因为只有当插入的节点的父亲是红色的时候,此时红黑树的性质遭到破坏,需要旋转,再分1.叔父节点为红,此时只要改变颜色,但祖父节点颜色的改变可能会破坏红黑树的性质,所以要node = grandparent,继续向上,叔父为黑,这时需要旋转,所以得判断,自身的位置,也就是自己和父亲分别是左孩子还是右孩子,2.如果自身是右,父亲是左,的先把自己也旋转到左,再和自己是左,父亲也是左的情况一