红黑树

package main

import (
    "fmt"
    "unsafe"
)

/*
定义:
1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶结点(叶结点即指树尾端NIL指针或NULL结点)是黑的。
4)如果一个结点是红的,那么它的俩个儿子都是黑的。
5)对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。
*/
//红黑树(平衡二叉树)
type RBTree struct {
    index, height                 int
    isRed                         bool
    parent, leftChild, rightChild *RBTree
    ptr                           unsafe.Pointer //记录数据地址
}

func NewRBTree(index int, ptr unsafe.Pointer) *RBTree {
    return &RBTree{
        index:  index,
        isRed:  false,
        height: 1,
        ptr:    ptr,
    }
}

//判断一个节点是左孩子还是右孩子,排除根节点情况
func (root *RBTree) IsLeftChild() bool {
    if root.parent == nil {
        return false
    }
    return root.parent.leftChild == root
}

//左旋 左斜线的情况
func (h *Head) LeftRotate(root *RBTree) {
    var isParentLeft bool
    zufu := root.parent.parent
    isParentLeft = root.parent.IsLeftChild()
    root.leftChild = root.parent
    root.leftChild.parent = root
    root.leftChild.height++
    //将旋转得到的叶子节点左右孩子清空内存
    root.leftChild.leftChild = nil
    root.leftChild.rightChild = nil
    if zufu != nil {
        if isParentLeft {
            zufu.leftChild = root
        } else {
            zufu.rightChild = root
        }
        root.parent = zufu
        root.height = zufu.height + 1
    } else {
        h.ptr = root
        root.parent = nil
        root.height = 1
    }

    if root.rightChild != nil {
        root.rightChild.height--
    }
}

//右旋 右斜线的情况
func (h *Head) RightRotate(root *RBTree) {
    var isParentLeft bool
    zufu := root.parent.parent
    isParentLeft = root.parent.IsLeftChild()
    root.rightChild = root.parent
    root.rightChild.parent = root
    root.rightChild.height++
    //将旋转得到的叶子节点左右孩子清空内存
    root.rightChild.leftChild = nil
    root.rightChild.leftChild = nil
    if zufu != nil {
        if isParentLeft {
            zufu.leftChild = root
        } else {
            zufu.rightChild = root
        }
        root.parent = zufu
        root.height = zufu.height + 1
    } else {
        h.ptr = root
        root.parent = nil
        root.height = 1
    }

    if root.leftChild != nil {
        root.leftChild.height--
    }
}

func (h *Head) Insert(node *RBTree) {
    p := h.ptr
    q := p
    for p != nil {
        q = p
        if node.index == p.index {
            return
        }

        if node.index < p.index {
            p = p.leftChild
        } else {
            p = p.rightChild
        }
    }

    if q.index < node.index {
        q.rightChild = node
        node.parent = q
    }
    if q.index > node.index {
        q.leftChild = node
        node.parent = q
    }
    //插入的新节点是红色
    node.isRed = true
    node.height = q.height + 1
    //如果父节点是黑色,不需要进行调整
    if !q.isRed {
        return
    }

    //父节点是红色
    //1.叔叔节点为红色 ==>父节点和叔叔节点改黑色
    if q.parent.leftChild != nil && q.parent.rightChild != nil {
        q.parent.leftChild.isRed = false
        q.parent.rightChild.isRed = false
        return
    }

    //2.叔叔节点为空,新节点和父节点,祖父节点一条线上
    //a.父节点和新节点都是左孩子
    if q.IsLeftChild() && node.IsLeftChild() {
        h.RightRotate(q)
        q.isRed = false
        q.leftChild.isRed = true
        q.rightChild.isRed = true
        return
    }
    //b.父节点和新节点都是右孩子
    if !q.IsLeftChild() && !node.IsLeftChild() {
        h.LeftRotate(q)
        q.isRed = false
        q.leftChild.isRed = true
        q.rightChild.isRed = true
        return
    }

    //3.叔叔节点为空,新节点和父节点,祖父节点不在一条线上
    //a.父节点为右孩子,新节点为左孩子
    if !q.IsLeftChild() && node.IsLeftChild() {
        //对新节点右旋,变成一条线上
        h.RightRotate(node)
        //再对新节点左旋
        h.LeftRotate(node)
        node.isRed = false
        node.leftChild.isRed = true
        node.rightChild.isRed = true
        return
    }
    //b.父节点为左孩子,新节点为右孩子
    if q.IsLeftChild() && !node.IsLeftChild() {
        //对新节点左旋,变成一条线上
        h.LeftRotate(node)
        //再对新节点右旋
        h.RightRotate(node)
        node.isRed = false
        node.leftChild.isRed = true
        node.rightChild.isRed = true
        return
    }
}

//层次遍历
func Print(root *RBTree) {
    queq := make([]*RBTree, 0)
    if root == nil {
        return
    }
    i := 0
    queq = append(queq, root)
    for i < len(queq) {
        fmt.Println(queq[i].index, queq[i].height, queq[i].isRed, queq[i].parent)
        if queq[i].leftChild != nil {
            queq = append(queq, queq[i].leftChild)
        }
        if queq[i].rightChild != nil {
            queq = append(queq, queq[i].rightChild)
        }
        i++
    }
}

type Data struct {
    id   int
    name string
}

type Head struct {
    ptr *RBTree
}

func main() {
    //用链表头指向树的root地址
    test := []int{8, 7, 4, 5, 3, 2, 1}
    root := NewRBTree(6, unsafe.Pointer(&Data{10, "xxx"}))
    head := Head{root}
    fmt.Println(&root)
    fmt.Println(unsafe.Pointer(&root))
    for _, v := range test {
        head.Insert(&RBTree{index: v})
    }
    fmt.Println(&root)
    Print(head.ptr)
}

 

posted @ 2018-03-09 16:12  孤独风中一匹狼  阅读(219)  评论(0编辑  收藏  举报