package helper const ( RED = true BLACK = false ) // 节点 type RBNode struct { Color bool // true == 红 false == 黑 Parent, Left, Right *RBNode Value, Index int } type RBTree struct { Root *RBNode } /* * 对红黑树的节点(x)进行左旋转 * * 左旋示意图(对节点 x 进行左旋): * px px * / / * x y * / \ --(左旋)-. / \ # * lx y x ry * / \ / \ * ly ry lx ly * * */ func (t *RBTree) leftSpin(node *RBNode) { // 先提出自己的 右子 y := node.Right // 自己的新右子 是前右子的左子 node.Right = y.Left if nil != y.Left { y.Left.Parent = node } // 你以前的爹,就是我现在的爹 y.Parent = node.Parent // 如果被旋转的节点是 之前树的根 // 那么,新的跟就是 y 节点 if nil == node.Parent { t.Root = y } else { // 被旋转的是普通节点时, 需要结合自身的父亲来确认自己之前是属于 左子还是右子 if node.Parent.Left == node { // 被旋转节点之前是 左子时 // 用 y 来作为之前 该节点父亲的 新左子 node.Parent.Left = y } else { // 否则,是 右子 node.Parent.Right = y } } // 将 node 设为 y 的左子 y.Left = node // 将 y 设为 node 的新父亲 node.Parent = y } /* * 对红黑树的节点(y)进行右旋转 * * 右旋示意图(对节点 y 进行左旋): * py py * / / * y x * / \ --(右旋)-. / \ # * x ry lx y * / \ / \ # * lx rx rx ry * */ func (t *RBTree) rightSpin(node *RBNode) { // 先提出自己的 左子 x := node.Left node.Left = x.Right if nil != x.Left { x.Right.Parent = node } x.Parent = node.Parent // 如果被旋转的节点是 之前树的根 // 那么,新的跟就是 x 节点 if nil == node.Parent { t.Root = x } else { if node.Parent.Right == node { node.Parent.Right = x } else { node.Parent.Left = x } } x.Right = node node.Parent = x } func insertValue(tree *RBTree, val, index int) { node := &RBNode{Value: val, Index: index, Color: BLACK} if nil == tree.Root { tree.Root = node } else { tree.insert(node) } } func (t *RBTree) insert(node *RBNode) { //int cmp; var tmpNode *RBNode root := t.Root // 1. 将红黑树当作一颗二叉查找树,将节点添加到二叉查找树中。 for nil != root { if node.Value < root.Value { root = root.Left } else { root = root.Right } tmpNode = root } node.Parent = tmpNode if nil != tmpNode { if node.Value < tmpNode.Value { tmpNode.Left = node } else { tmpNode.Right = node } } else { t.Root = node } // 2. 设置节点的颜色为红色 node.Color = RED // 3. 将它重新修正为一颗二叉查找树 t.adjustRBTree(node) } // 修正树 func (t *RBTree) adjustRBTree(node *RBNode) { var parent, gparent *RBNode // 父亲 和 祖父 // 若“父节点存在,并且父节点的颜色是红色” for nil != node.Parent && RED == node.Parent.Color { parent = node.Parent gparent = parent.Parent //若“父节点”是“祖父节点的左孩子” if parent == gparent.Left { // Case 1条件:叔叔节点是红色 uncle := gparent.Right if nil != uncle && RED == uncle.Color { uncle.Color = BLACK parent.Color = BLACK gparent.Color = RED node = gparent continue } // Case 2条件:叔叔是黑色,且当前节点是右孩子 if node == parent.Right { var tmp *RBNode t.leftSpin(parent) tmp = parent parent = node node = tmp } // Case 3条件:叔叔是黑色,且当前节点是左孩子。 parent.Color = BLACK gparent.Color = RED t.rightSpin(gparent) } else { //若“z的父节点”是“z的祖父节点的右孩子” // Case 1条件:叔叔节点是红色 uncle := gparent.Left if nil != uncle && RED == uncle.Color { uncle.Color = BLACK parent.Color = BLACK gparent.Color = RED node = gparent continue } // Case 2条件:叔叔是黑色,且当前节点是左孩子 if node == parent.Left { var tmp *RBNode t.rightSpin(parent) tmp = parent parent = node node = tmp } // Case 3条件:叔叔是黑色,且当前节点是右孩子。 parent.Color = BLACK gparent.Color = RED t.leftSpin(gparent) } } // 将根节点设为黑色 t.Root.Color = BLACK } func (t *RBTree) serch(key int) int { return serch(t.Root, key) } func serch(node *RBNode, key int) int { if nil == node { return -1 } if key < node.Value { return serch(node.Left, key) } else if key > node.Value { return serch(node.Right, key) } else { return node.Index } }