github.com/joshvarga/voronoi@v0.0.0-20180211004454-2fd26fbdfffb/bt_tree.go (about)

     1  // MIT License: See https://github.com/pzsz/voronoi/LICENSE.md
     2  
     3  // Author: Przemyslaw Szczepaniak (przeszczep@gmail.com)
     4  // Port of Raymond Hill's (rhill@raymondhill.net) javascript implementation 
     5  // of Steven  Forune's algorithm to compute Voronoi diagrams
     6  
     7  package voronoi
     8  
     9  // Red-Black tree code (based on C version of "rbtree" by Franck Bui-Huu
    10  // https://github.com/fbuihuu/libtree/blob/master/rb.c
    11  type rbTree struct {
    12  	root *rbNode
    13  }
    14  
    15  type rbNodeValue interface {
    16  	bindToNode(node *rbNode)
    17  	getNode() *rbNode
    18  }
    19  
    20  type rbNode struct {
    21  	value    rbNodeValue
    22  	left     *rbNode
    23  	right    *rbNode
    24  	parent   *rbNode
    25  	previous *rbNode
    26  	next     *rbNode
    27  	red      bool
    28  }
    29  
    30  func (t *rbTree) insertSuccessor(node *rbNode, vsuccessor rbNodeValue) {
    31  	successor := &rbNode{value: vsuccessor}
    32  	vsuccessor.bindToNode(successor)
    33  
    34  	var parent *rbNode
    35  	if node != nil {
    36  		// >>> rhill 2011-05-27: Performance: cache previous/next nodes
    37  		successor.previous = node
    38  		successor.next = node.next
    39  		if node.next != nil {
    40  			node.next.previous = successor
    41  		}
    42  		node.next = successor
    43  		// <<<
    44  		if node.right != nil {
    45  			// in-place expansion of node.rbRight.getFirst()
    46  			node = node.right
    47  			for ; node.left != nil; node = node.left {
    48  			}
    49  			node.left = successor
    50  		} else {
    51  			node.right = successor
    52  		}
    53  		parent = node
    54  
    55  		// rhill 2011-06-07: if node is null, successor must be inserted
    56  		// to the left-most part of the tree
    57  	} else if t.root != nil {
    58  		node = t.getFirst(t.root)
    59  		// >>> Performance: cache previous/next nodes
    60  		successor.previous = nil
    61  		successor.next = node
    62  		node.previous = successor
    63  		// <<<
    64  		node.left = successor
    65  		parent = node
    66  	} else {
    67  		// >>> Performance: cache previous/next nodes
    68  		successor.previous = nil
    69  		successor.next = nil
    70  		// <<<
    71  		t.root = successor
    72  		parent = nil
    73  	}
    74  	successor.left = nil
    75  	successor.right = nil
    76  	successor.parent = parent
    77  	successor.red = true
    78  	// Fixup the modified tree by recoloring nodes and performing
    79  	// rotations (2 at most) hence the red-black tree properties are
    80  	// preserved.
    81  	var grandpa, uncle *rbNode
    82  	node = successor
    83  	for parent != nil && parent.red {
    84  		grandpa = parent.parent
    85  		if parent == grandpa.left {
    86  			uncle = grandpa.right
    87  			if uncle != nil && uncle.red {
    88  				parent.red = false
    89  				uncle.red = false
    90  				grandpa.red = true
    91  				node = grandpa
    92  			} else {
    93  				if node == parent.right {
    94  					t.rotateLeft(parent)
    95  					node = parent
    96  					parent = node.parent
    97  				}
    98  				parent.red = false
    99  				grandpa.red = true
   100  				t.rotateRight(grandpa)
   101  			}
   102  		} else {
   103  			uncle = grandpa.left
   104  			if uncle != nil && uncle.red {
   105  				parent.red = false
   106  				uncle.red = false
   107  				grandpa.red = true
   108  				node = grandpa
   109  			} else {
   110  				if node == parent.left {
   111  					t.rotateRight(parent)
   112  					node = parent
   113  					parent = node.parent
   114  				}
   115  				parent.red = false
   116  				grandpa.red = true
   117  				t.rotateLeft(grandpa)
   118  			}
   119  		}
   120  		parent = node.parent
   121  	}
   122  	t.root.red = false
   123  }
   124  
   125  func (t *rbTree) removeNode(node *rbNode) {
   126  	// >>> rhill 2011-05-27: Performance: cache previous/next nodes
   127  	if node.next != nil {
   128  		node.next.previous = node.previous
   129  	}
   130  	if node.previous != nil {
   131  		node.previous.next = node.next
   132  	}
   133  	node.next = nil
   134  	node.previous = nil
   135  	// <<<
   136  	var parent = node.parent
   137  	var left = node.left
   138  	var right = node.right
   139  	var next *rbNode
   140  	if left == nil {
   141  		next = right
   142  	} else if right == nil {
   143  		next = left
   144  	} else {
   145  		next = t.getFirst(right)
   146  	}
   147  	if parent != nil {
   148  		if parent.left == node {
   149  			parent.left = next
   150  		} else {
   151  			parent.right = next
   152  		}
   153  	} else {
   154  		t.root = next
   155  	}
   156  	// enforce red-black rules
   157  	isRed := false
   158  	if left != nil && right != nil {
   159  		isRed = next.red
   160  		next.red = node.red
   161  		next.left = left
   162  		left.parent = next
   163  		if next != right {
   164  			parent = next.parent
   165  			next.parent = node.parent
   166  			node = next.right
   167  			parent.left = node
   168  			next.right = right
   169  			right.parent = next
   170  		} else {
   171  			next.parent = parent
   172  			parent = next
   173  			node = next.right
   174  		}
   175  	} else {
   176  		isRed = node.red
   177  		node = next
   178  	}
   179  	// 'node' is now the sole successor's child and 'parent' its
   180  	// new parent (since the successor can have been moved)
   181  	if node != nil {
   182  		node.parent = parent
   183  	}
   184  	// the 'easy' cases
   185  	if isRed {
   186  		return
   187  	}
   188  	if node != nil && node.red {
   189  		node.red = false
   190  		return
   191  	}
   192  	// the other cases
   193  	var sibling *rbNode
   194  	for {
   195  		if node == t.root {
   196  			break
   197  		}
   198  		if node == parent.left {
   199  			sibling = parent.right
   200  			if sibling.red {
   201  				sibling.red = false
   202  				parent.red = true
   203  				t.rotateLeft(parent)
   204  				sibling = parent.right
   205  			}
   206  			if (sibling.left != nil && sibling.left.red) || (sibling.right != nil && sibling.right.red) {
   207  				if sibling.right == nil || !sibling.right.red {
   208  					sibling.left.red = false
   209  					sibling.red = true
   210  					t.rotateRight(sibling)
   211  					sibling = parent.right
   212  				}
   213  				sibling.red = parent.red
   214  				parent.red = false
   215  				sibling.right.red = false
   216  				t.rotateLeft(parent)
   217  				node = t.root
   218  				break
   219  			}
   220  		} else {
   221  			sibling = parent.left
   222  			if sibling.red {
   223  				sibling.red = false
   224  				parent.red = true
   225  				t.rotateRight(parent)
   226  				sibling = parent.left
   227  			}
   228  			if (sibling.left != nil && sibling.left.red) || (sibling.right != nil && sibling.right.red) {
   229  				if sibling.left == nil || !sibling.left.red {
   230  					sibling.right.red = false
   231  					sibling.red = true
   232  					t.rotateLeft(sibling)
   233  					sibling = parent.left
   234  				}
   235  				sibling.red = parent.red
   236  				parent.red = false
   237  				sibling.left.red = false
   238  				t.rotateRight(parent)
   239  				node = t.root
   240  				break
   241  			}
   242  		}
   243  		sibling.red = true
   244  		node = parent
   245  		parent = parent.parent
   246  		if node.red {
   247  			break
   248  		}
   249  	}
   250  	if node != nil {
   251  		node.red = false
   252  	}
   253  }
   254  
   255  func (t *rbTree) rotateLeft(node *rbNode) {
   256  	var p = node
   257  	var q = node.right // can't be null
   258  	var parent = p.parent
   259  	if parent != nil {
   260  		if parent.left == p {
   261  			parent.left = q
   262  		} else {
   263  			parent.right = q
   264  		}
   265  	} else {
   266  		t.root = q
   267  	}
   268  	q.parent = parent
   269  	p.parent = q
   270  	p.right = q.left
   271  	if p.right != nil {
   272  		p.right.parent = p
   273  	}
   274  	q.left = p
   275  }
   276  
   277  func (t *rbTree) rotateRight(node *rbNode) {
   278  	var p = node
   279  	var q = node.left // can't be null
   280  	var parent = p.parent
   281  	if parent != nil {
   282  		if parent.left == p {
   283  			parent.left = q
   284  		} else {
   285  			parent.right = q
   286  		}
   287  	} else {
   288  		t.root = q
   289  	}
   290  	q.parent = parent
   291  	p.parent = q
   292  	p.left = q.right
   293  	if p.left != nil {
   294  		p.left.parent = p
   295  	}
   296  	q.right = p
   297  }
   298  
   299  func (t *rbTree) getFirst(node *rbNode) *rbNode {
   300  	for node.left != nil {
   301  		node = node.left
   302  	}
   303  	return node
   304  }
   305  
   306  func (t *rbTree) getLast(node *rbNode) *rbNode {
   307  	for node.right != nil {
   308  		node = node.right
   309  	}
   310  	return node
   311  }