紅黑樹插入與刪除完整代碼(dart語言實現)

  以前分析了紅黑樹的刪除,這裏附上紅黑樹的完整版代碼,包括查找、插入、刪除等。刪除後修復實現了兩種算法,均比以前的更爲簡潔。一種是我本身的實現,代碼很是簡潔,行數更少;一種是Linux、Java等源碼版本的實現,實現的略爲複雜,但效率更高。兩種算法通過測試,在百萬級的數據上效率不分伯仲;1000萬的數據中,我本身的實現比Linux內核版本的運行時間多2秒左右。node

  紅黑樹的插入相對簡單,本文中的代碼實現與Linux源碼版本也略有差別,效率差異不大。算法

  其餘方法,如查找、遍歷等,比較簡單,很少作解釋。遍歷支持前序、中序、後序遍歷。post

  在研究紅黑樹的過程當中,爲了完全弄懂插入與刪除,畫了無數的圖,以刪除修復爲例,根據父親節點、兄弟節點、兄弟節點的左右子節點的空、紅、黑的狀況,窮舉了36中狀況,再進行概括合併。而弄明白之後,發現是如此的簡單;實現了多種寫法,最後總結爲兩種最簡潔的實現,並進行性能測試。還寫了檢查一棵樹是不是紅黑樹的代碼,將在下篇博客中發佈。性能

  至此,二叉樹和紅黑樹研究完畢。代碼以下:測試

 1 import 'tree_node.dart';  2 import 'tree_exception.dart';  3 import 'traverse_order.dart';  4 
 5 class RBTree<E extends Comparable<E>> {  6   RBTNode<E> _root;  7   int _nodeNumbers;  8 
 9   RBTree() : _nodeNumbers = 0;  10 
 11   factory RBTree.from(Iterable<Comparable<E>> elements) {  12     var tree = RBTree<E>();  13     for (var e in elements) tree.insert(e);  14     return tree;  15  }  16 
 17   bool get isEmpty => _root == null;  18   int get nodeNumbers => _nodeNumbers;  19   RBTNode<E> get root => _root;  20 
 21   void clear() {  22     _root = null;  23     _nodeNumbers = 0;  24  }  25 
 26   bool contains(E value) => find(value) != null;  27 
 28   bool delete(E value) => _delete(value, _fixAfterDelete);  29 
 30   // the implement in Linux core.
 31   bool quickDelete(E value) => _delete(value, _fixAfterDelete2);  32 
 33   RBTNode<E> find(E value) {  34     var current = _root;  35     while (current != null) {  36       var c = value.compareTo(current.value);  37       if (c == 0) break;  38       current = c < 0 ? current.left : current.right;  39  }  40     return current;  41  }  42 
 43   void insert(E value) {  44     var inserted = RBTNode<E>(value);  45  _insert(inserted);  46  _fixAfterInsert(inserted);  47  }  48 
 49  E get max {  50     if (isEmpty) throw TreeEmptyException();  51     var maxNode = _root;  52     while (maxNode.right != null) maxNode = maxNode.right;  53     return maxNode.value;  54  }  55 
 56  E get min {  57     if (isEmpty) throw TreeEmptyException();  58     return _minNode(_root).value;  59  }  60 
 61   void traverse(void f(E e), [TraverseOrder order = TraverseOrder.inOrder]) =>
 62  _traverse(_root, order, f);  63 
 64   void _insert(RBTNode<E> inserted) {  65     RBTNode<E> p, c = _root;  66     while (c != null) {  67       p = c;  68       c = inserted.value.compareTo(c.value) <= 0 ? c.left : c.right;  69  }  70 
 71     if (p == null) {  72       _root = inserted;  73     } else if (inserted.value.compareTo(p.value) <= 0) {  74       p.left = inserted;  75     } else {  76       p.right = inserted;  77  }  78     inserted.parent = p;  79     _nodeNumbers++;  80  }  81 
 82   void _fixAfterInsert(RBTNode<E> node) {  83     while (_hasRedFather(node) && _hasRedUncle(node)) {  84       var g = _gparent(node);  85  g.left.paintBlack();  86  g.right.paintBlack();  87  g.paintRed();  88       node = g;  89  }  90 
 91     if (_hasRedFather(node)) {  92       var g = _gparent(node);  93       if (node.parent == g.left) {  94         if (node == node.parent.right) {  95  _rotateLeft(node.parent);  96           node = node.left;  97  }  98  _rotateRight(g);  99       } else { 100         if (node == node.parent.left) { 101  _rotateRight(node.parent); 102           node = node.right; 103  } 104  _rotateLeft(g); 105  } 106  node.parent.paintBlack(); 107  g.paintRed(); 108  } 109  _root.paintBlack(); 110  } 111 
112   bool _hasRedFather(RBTNode<E> node) =>
113       node.parent != null && node.parent.isRed; 114 
115   bool _hasRedUncle(RBTNode<E> node) { 116     var gparent = _gparent(node); 117     var uncle = node.parent == gparent.left ? gparent.right : gparent.left; 118     return uncle != null && uncle.isRed; 119  } 120 
121   RBTNode _gparent(RBTNode<E> node) => node.parent.parent; 122 
123   bool _delete(E value, void _fix(RBTNode<E> p, bool isLeft)) { 124     var d = find(value); 125     if (d == null) return false; 126 
127     if (d.left != null && d.right != null) { 128       var s = _successor(d); 129       d.value = s.value; 130       d = s; 131  } 132     var rp = d.left ?? d.right; 133     rp?.parent = d.parent; 134     if (d.parent == null) 135       _root = rp; 136     else if (d == d.parent.left) 137       d.parent.left = rp; 138     else
139       d.parent.right = rp; 140 
141     if (rp != null) 142  rp.paintBlack(); 143     else if (d.isBlack && d.parent != null) 144       _fix(d.parent, d.parent.left == null); 145 
146     _nodeNumbers--; 147     return true; 148  } 149 
150   RBTNode<E> _successor(RBTNode<E> d) =>
151       d.right != null ? _minNode(d.right) : d.left; 152 
153   void _fixAfterDelete(RBTNode<E> p, bool isLeft) { 154     var c = isLeft ? p.right : p.left; 155     if (isLeft) { 156       if (c.isRed) { 157  p.paintRed(); 158  c.paintBlack(); 159  _rotateLeft(p); 160         c = p.right; 161  } 162       if (c.left != null && c.left.isRed) { 163  c.left.paint(p.color); 164         if (p.isRed) p.paintBlack(); 165  _rotateRight(c); 166  _rotateLeft(p); 167       } else { 168  _rotateLeft(p); 169         if (p.isBlack) { 170  p.paintRed(); 171           if (c.parent != null) _fixAfterDelete(c.parent, c == c.parent.left); 172  } 173  } 174     } else { 175       if (c.isRed) { 176  p.paintRed(); 177  c.paintBlack(); 178  _rotateRight(p); 179         c = p.left; 180  } 181       if (c.right != null && c.right.isRed) { 182  c.right.paint(p.color); 183         if (p.isRed) p.paintBlack(); 184  _rotateLeft(c); 185  _rotateRight(p); 186       } else { 187  _rotateRight(p); 188         if (p.isBlack) { 189  p.paintRed(); 190           if (c.parent != null) _fixAfterDelete(c.parent, c == c.parent.left); 191  } 192  } 193  } 194  } 195 
196   // the implement in Linux core.
197   void _fixAfterDelete2(RBTNode<E> p, bool isLeft) { 198     var c = isLeft ? p.right : p.left; 199     if (isLeft) { 200       if (c.isRed) { 201  p.paintRed(); 202  c.paintBlack(); 203  _rotateLeft(p); 204         c = p.right; 205  } 206       if ((c.left != null && c.left.isRed) ||
207           (c.right != null && c.right.isRed)) { 208         if (c.right == null || c.right.isBlack) { 209  _rotateRight(c); 210           c = p.right; 211  } 212  c.paint(p.color); 213  p.paintBlack(); 214  c.right.paintBlack(); 215  _rotateLeft(p); 216       } else { 217  c.paintRed(); 218         if (p.isRed) 219  p.paintBlack(); 220         else if (p.parent != null) 221           _fixAfterDelete2(p.parent, p == p.parent.left); 222  } 223     } else { 224       if (c.isRed) { 225  p.paintRed(); 226  c.paintBlack(); 227  _rotateRight(p); 228         c = p.left; 229  } 230       if ((c.left != null && c.left.isRed) ||
231           (c.right != null && c.right.isRed)) { 232         if (c.left == null || c.left.isBlack) { 233  _rotateLeft(c); 234           c = p.left; 235  } 236  c.paint(p.color); 237  p.paintBlack(); 238  c.left.paintBlack(); 239  _rotateRight(p); 240       } else { 241  c.paintRed(); 242         if (p.isRed) 243  p.paintBlack(); 244         else if (p.parent != null) 245           _fixAfterDelete2(p.parent, p == p.parent.left); 246  } 247  } 248  } 249 
250   void _rotateLeft(RBTNode<E> node) { 251     var r = node.right, p = node.parent; 252     r.parent = p; 253     if (p == null) 254       _root = r; 255     else if (p.left == node) 256       p.left = r; 257     else
258       p.right = r; 259 
260     node.right = r.left; 261     r.left?.parent = node; 262     r.left = node; 263     node.parent = r; 264  } 265 
266   void _rotateRight(RBTNode<E> node) { 267     var l = node.left, p = node.parent; 268     l.parent = p; 269     if (p == null) 270       _root = l; 271     else if (p.left == node) 272       p.left = l; 273     else
274       p.right = l; 275 
276     node.left = l.right; 277     l.right?.parent = node; 278     l.right = node; 279     node.parent = l; 280  } 281 
282   RBTNode<E> _minNode(RBTNode<E> r) => r.left == null ? r : _minNode(r.left); 283 
284   void _traverse(RBTNode<E> s, TraverseOrder order, void f(E e)) { 285     if (s == null) return; 286     switch (order) { 287       case TraverseOrder.inOrder: 288  _traverse(s.left, order, f); 289  f(s.value); 290  _traverse(s.right, order, f); 291         break; 292       case TraverseOrder.preOrder: 293  f(s.value); 294  _traverse(s.left, order, f); 295  _traverse(s.right, order, f); 296         break; 297       case TraverseOrder.postOrder: 298  _traverse(s.left, order, f); 299  _traverse(s.right, order, f); 300  f(s.value); 301         break; 302       default: 303         break; 304  } 305  } 306 }
相關文章
相關標籤/搜索