// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package ssa import "fmt" const ( rankLeaf rbrank = 1 rankZero rbrank = 0 ) type rbrank int8 // RBTint32 is a red-black tree with data stored at internal nodes, // following Tarjan, Data Structures and Network Algorithms, // pp 48-52, using explicit rank instead of red and black. // Deletion is not yet implemented because it is not yet needed. // Extra operations glb, lub, glbEq, lubEq are provided for // use in sparse lookup algorithms. type RBTint32 struct { root *node32 // An extra-clever implementation will have special cases // for small sets, but we are not extra-clever today. } func (t *RBTint32) String() string { if t.root == nil { return "[]" } return "[" + t.root.String() + "]" } func (t *node32) String() string { s := "" if t.left != nil { s = t.left.String() + " " } s = s + fmt.Sprintf("k=%d,d=%v", t.key, t.data) if t.right != nil { s = s + " " + t.right.String() } return s } type node32 struct { // Standard conventions hold for left = smaller, right = larger left, right, parent *node32 data interface{} key int32 rank rbrank // From Tarjan pp 48-49: // If x is a node with a parent, then x.rank <= x.parent.rank <= x.rank+1. // If x is a node with a grandparent, then x.rank < x.parent.parent.rank. // If x is an "external [null] node", then x.rank = 0 && x.parent.rank = 1. // Any node with one or more null children should have rank = 1. } // makeNode returns a new leaf node with the given key and nil data. func (t *RBTint32) makeNode(key int32) *node32 { return &node32{key: key, rank: rankLeaf} } // IsEmpty reports whether t is empty. func (t *RBTint32) IsEmpty() bool { return t.root == nil } // IsSingle reports whether t is a singleton (leaf). func (t *RBTint32) IsSingle() bool { return t.root != nil && t.root.isLeaf() } // VisitInOrder applies f to the key and data pairs in t, // with keys ordered from smallest to largest. func (t *RBTint32) VisitInOrder(f func(int32, interface{})) { if t.root == nil { return } t.root.visitInOrder(f) } func (n *node32) Data() interface{} { if n == nil { return nil } return n.data } func (n *node32) keyAndData() (k int32, d interface{}) { if n == nil { k = 0 d = nil } else { k = n.key d = n.data } return } func (n *node32) Rank() rbrank { if n == nil { return 0 } return n.rank } // Find returns the data associated with key in the tree, or // nil if key is not in the tree. func (t *RBTint32) Find(key int32) interface{} { return t.root.find(key).Data() } // Insert adds key to the tree and associates key with data. // If key was already in the tree, it updates the associated data. // Insert returns the previous data associated with key, // or nil if key was not present. // Insert panics if data is nil. func (t *RBTint32) Insert(key int32, data interface{}) interface{} { if data == nil { panic("Cannot insert nil data into tree") } n := t.root var newroot *node32 if n == nil { n = t.makeNode(key) newroot = n } else { newroot, n = n.insert(key, t) } r := n.data n.data = data t.root = newroot return r } // Min returns the minimum element of t and its associated data. // If t is empty, then (0, nil) is returned. func (t *RBTint32) Min() (k int32, d interface{}) { return t.root.min().keyAndData() } // Max returns the maximum element of t and its associated data. // If t is empty, then (0, nil) is returned. func (t *RBTint32) Max() (k int32, d interface{}) { return t.root.max().keyAndData() } // Glb returns the greatest-lower-bound-exclusive of x and its associated // data. If x has no glb in the tree, then (0, nil) is returned. func (t *RBTint32) Glb(x int32) (k int32, d interface{}) { return t.root.glb(x, false).keyAndData() } // GlbEq returns the greatest-lower-bound-inclusive of x and its associated // data. If x has no glbEQ in the tree, then (0, nil) is returned. func (t *RBTint32) GlbEq(x int32) (k int32, d interface{}) { return t.root.glb(x, true).keyAndData() } // Lub returns the least-upper-bound-exclusive of x and its associated // data. If x has no lub in the tree, then (0, nil) is returned. func (t *RBTint32) Lub(x int32) (k int32, d interface{}) { return t.root.lub(x, false).keyAndData() } // LubEq returns the least-upper-bound-inclusive of x and its associated // data. If x has no lubEq in the tree, then (0, nil) is returned. func (t *RBTint32) LubEq(x int32) (k int32, d interface{}) { return t.root.lub(x, true).keyAndData() } func (t *node32) isLeaf() bool { return t.left == nil && t.right == nil } func (t *node32) visitInOrder(f func(int32, interface{})) { if t.left != nil { t.left.visitInOrder(f) } f(t.key, t.data) if t.right != nil { t.right.visitInOrder(f) } } func (t *node32) maxChildRank() rbrank { if t.left == nil { if t.right == nil { return rankZero } return t.right.rank } if t.right == nil { return t.left.rank } if t.right.rank > t.left.rank { return t.right.rank } return t.left.rank } func (t *node32) minChildRank() rbrank { if t.left == nil || t.right == nil { return rankZero } if t.right.rank < t.left.rank { return t.right.rank } return t.left.rank } func (t *node32) find(key int32) *node32 { for t != nil { if key < t.key { t = t.left } else if key > t.key { t = t.right } else { return t } } return nil } func (t *node32) min() *node32 { if t == nil { return t } for t.left != nil { t = t.left } return t } func (t *node32) max() *node32 { if t == nil { return t } for t.right != nil { t = t.right } return t } func (t *node32) glb(key int32, allow_eq bool) *node32 { var best *node32 for t != nil { if key <= t.key { if key == t.key && allow_eq { return t } // t is too big, glb is to left. t = t.left } else { // t is a lower bound, record it and seek a better one. best = t t = t.right } } return best } func (t *node32) lub(key int32, allow_eq bool) *node32 { var best *node32 for t != nil { if key >= t.key { if key == t.key && allow_eq { return t } // t is too small, lub is to right. t = t.right } else { // t is a upper bound, record it and seek a better one. best = t t = t.left } } return best } func (t *node32) insert(x int32, w *RBTint32) (newroot, newnode *node32) { // defaults newroot = t newnode = t if x == t.key { return } if x < t.key { if t.left == nil { n := w.makeNode(x) n.parent = t t.left = n newnode = n return } var new_l *node32 new_l, newnode = t.left.insert(x, w) t.left = new_l new_l.parent = t newrank := 1 + new_l.maxChildRank() if newrank > t.rank { if newrank > 1+t.right.Rank() { // rotations required if new_l.left.Rank() < new_l.right.Rank() { // double rotation t.left = new_l.rightToRoot() } newroot = t.leftToRoot() return } else { t.rank = newrank } } } else { // x > t.key if t.right == nil { n := w.makeNode(x) n.parent = t t.right = n newnode = n return } var new_r *node32 new_r, newnode = t.right.insert(x, w) t.right = new_r new_r.parent = t newrank := 1 + new_r.maxChildRank() if newrank > t.rank { if newrank > 1+t.left.Rank() { // rotations required if new_r.right.Rank() < new_r.left.Rank() { // double rotation t.right = new_r.leftToRoot() } newroot = t.rightToRoot() return } else { t.rank = newrank } } } return } func (t *node32) rightToRoot() *node32 { // this // left right // rl rr // // becomes // // right // this rr // left rl // right := t.right rl := right.left right.parent = t.parent right.left = t t.parent = right // parent's child ptr fixed in caller t.right = rl if rl != nil { rl.parent = t } return right } func (t *node32) leftToRoot() *node32 { // this // left right // ll lr // // becomes // // left // ll this // lr right // left := t.left lr := left.right left.parent = t.parent left.right = t t.parent = left // parent's child ptr fixed in caller t.left = lr if lr != nil { lr.parent = t } return left } // next returns the successor of t in a left-to-right // walk of the tree in which t is embedded. func (t *node32) next() *node32 { // If there is a right child, it is to the right r := t.right if r != nil { return r.min() } // if t is p.left, then p, else repeat. p := t.parent for p != nil { if p.left == t { return p } t = p p = t.parent } return nil } // prev returns the predecessor of t in a left-to-right // walk of the tree in which t is embedded. func (t *node32) prev() *node32 { // If there is a left child, it is to the left l := t.left if l != nil { return l.max() } // if t is p.right, then p, else repeat. p := t.parent for p != nil { if p.right == t { return p } t = p p = t.parent } return nil }