package algorithm
import (
"github.com/golang/glog"
)
type Tree struct {
Left *Tree
Right *Tree
Value int64
Height int64
}
func (t *Tree) AddNode(value int64) *Tree {
if t == nil {
return &Tree{
Left: nil,
Right: nil,
Value: value,
Height: 0,
}
}
if t.Value > value {
t.Left = t.Left.AddNode(value)
t.GetHeight()
if (t.Right == nil && t.Left.Height > 0) || (t.Right != nil && t.Left.Height-t.Right.Height > 1) {
if t.Left.Left == nil || t.Left.Left.Height < t.Left.Right.Height {
a := t.DoubleRotateLR()
a.Left.GetHeight()
a.Right.GetHeight()
a.GetHeight()
return a
}
if t.Left.Right == nil || t.Left.Left.Height > t.Left.Right.Height {
a := t.SingleRotateLeft()
a.Right.GetHeight()
a.GetHeight()
return a
}
}
} else {
t.Right = t.Right.AddNode(value)
t.GetHeight()
if (t.Left == nil && t.Right.Height > 0) || (t.Left != nil && t.Right.Height-t.Left.Height > 1) {
if t.Right.Left == nil || t.Right.Left.Height < t.Right.Right.Height {
a := t.SingleRotateRight()
a.Left.GetHeight()
a.GetHeight()
return a
}
if t.Right.Right == nil || t.Right.Left.Height > t.Right.Right.Height {
a := t.DoubleRotateRL()
a.Left.GetHeight()
a.Right.GetHeight()
a.GetHeight()
return a
}
}
}
return t
}
func (t *Tree) SingleRotateLeft() *Tree {
node := t.Left
t.Left = node.Right
node.Right = t
return node
}
func (t *Tree) SingleRotateRight() *Tree {
node := t.Right
t.Right = node.Left
node.Left = t
return node
}
func (t *Tree) DoubleRotateLR() *Tree {
t.Left = t.Left.SingleRotateRight()
return t.SingleRotateLeft()
}
func (t *Tree) DoubleRotateRL() *Tree {
t.Right = t.Right.SingleRotateLeft()
return t.SingleRotateRight()
}
func (t *Tree) GetHeight() {
switch {
case t.Left == nil && t.Right == nil:
t.Height = 0
return
case t.Left != nil && t.Right == nil:
t.Height = t.Left.Height + 1
return
case t.Left == nil && t.Right != nil:
t.Height = t.Right.Height + 1
return
case t.Left != nil && t.Right != nil:
if t.Left.Height > t.Right.Height {
t.Height = t.Left.Height + 1
} else {
t.Height = t.Right.Height + 1
}
return
}
t.Height = 0
}
func (t *Tree) Read() {
if t.Left != nil {
t.Left.Read()
}
glog.Info("value:", t.Value, " height:", t.Height)
if t.Right != nil {
t.Right.Read()
}
}
func Test() {
var res []int64
var t *Tree
for i := int64(0); i < 10; i++ {
res = append(res, i)
if t == nil {
t = &Tree{
Left: nil,
Right: nil,
Value: i,
Height: 0,
}
} else {
t = t.AddNode(i)
}
}
t.Read()
glog.Info(t.Value)
}