func (t *AvlTree) lookupNode(lt c.LookupType, data c.Comparable) (*avlNode, bool) { if t.root == nil { return nil, false } cn := t.root for { r := data.CompareTo(cn.data) if r == 0 { return cn, true } if r < 0 { if cn.l == nil { if lt == c.GTE { return cn, false } return cn.prv, false } cn = cn.l } else { if cn.r == nil { if lt == c.LTE { return cn, false } return cn.nxt, false } cn = cn.r } } }
func Pair(c1, c2 c.Comparable) Set { r := c1.CompareTo(c2) if r == 0 { return Singleton(c1) } if r < 0 { return &pairSet{x: c1, y: c2} } else { return &pairSet{x: c2, y: c1} } }
// Insert adds or replaces a value in the tree. If there is already an equal value, // it is replaced and the old value returned. Otherwise, nil is returned. func (t *AvlTree) Insert(data c.Comparable) c.Comparable { if t.root == nil { t.root = &avlNode{ data: data, } t.size++ t.head = t.root t.tail = t.root return nil } cn := t.root var r int8 for { r = data.CompareTo(cn.data) if r == 0 { break } if r < 0 { if cn.l == nil { break } cn = cn.l } else { if cn.r == nil { break } cn = cn.r } } if r == 0 { oldData := cn.data cn.data = data return oldData } nn := &avlNode{ data: data, p: cn, } if r < 0 { nn.prv = cn.prv nn.nxt = cn if cn.prv != nil { cn.prv.nxt = nn } else { t.head = nn } cn.prv = nn cn.l = nn cn.balance-- } else { nn.nxt = cn.nxt nn.prv = cn if cn.nxt != nil { cn.nxt.prv = nn } else { t.tail = nn } cn.nxt = nn cn.r = nn cn.balance++ } t.size++ for { switch cn.balance { case 0: { // Depth did not increase, we are done. return nil } case -1: fallthrough case 1: { // Depth increased, propagate. if cn.p != nil { if cn.p.l == cn { cn.p.balance-- } else { cn.p.balance++ } cn = cn.p } else { return nil // At root, done. } } case -2: fallthrough case 2: { np, changed := t.rebalanceAtNode(cn) if changed { // Change offset the insertion height change, we're done. return nil } cn = np } } } }