package main

import (
	"fmt"
	"strconv"
	"strings"
)

type Node struct {
	Item       int
	LeftChild  *Node
	RightChild *Node
}

//根节点
var root *Node

//打印二叉树
func PrintTree(head *Node, height int, to string, length int) {
	if head == nil {
		return
	}
	PrintTree(head.RightChild, height+1, "right", length)
	val := to + "\"" + strconv.Itoa(head.Item) + "\"" + to
	lenM := len([]rune(val))
	lenL := (length - lenM) / 2
	lenR := length - lenM - lenL
	val = GetSpace(lenL) + val + GetSpace(lenR)
	fmt.Println(GetSpace(height*length), val)
	PrintTree(head.LeftChild, height+1, "left", length)
}

//空格个数
func GetSpace(num int) string {
	space := " "
	var builder strings.Builder
	for i := 0; i < num; i++ {
		fmt.Fprint(&builder, space)
	}
	return builder.String()

}

//查找制定节点
func Find(key int) *Node {
	current := root
	for ; current != nil; {
		if current.Item > key {
			current = current.LeftChild
		} else if current.Item < key {
			current = current.RightChild
		} else {
			return current
		}
	}
	return nil
}

//插入
func Insert(data int) bool {
	newNode := Node{Item: data}
	if root == nil {
		root = &newNode
		return true
	} else {
		current := root
		var parentNode *Node
		for ; current != nil; {
			parentNode = current
			if current.Item > data {
				current = current.LeftChild
				if current == nil {
					parentNode.LeftChild = &newNode
					return true
				}
			} else {
				current = current.RightChild
				if current == nil {
					parentNode.RightChild = &newNode
					return true
				}
			}
		}
	}
	return false
}

//中序遍历
func InfixOrder(current *Node) {
	if current != nil {
		InfixOrder(current.LeftChild)
		fmt.Println(string(current.Item) + " ")
		InfixOrder(current.RightChild)
	}
}

//前序遍历
func PreOrder(current *Node) {
	if current == nil {
		fmt.Println(string(current.Item) + " ")
		InfixOrder(current.LeftChild)
		InfixOrder(current.RightChild)
	}
}

//后序遍历
func PostOrder(current *Node) {
	if current != nil {
		InfixOrder(current.LeftChild)
		InfixOrder(current.RightChild)
		fmt.Println(string(current.Item) + " ")
	}
}

//查找最大值
func FindMax() *Node {
	current := root
	maxNode := current
	for ; current != nil; {
		maxNode = current
		current = current.RightChild
	}
	return maxNode
}

//查找最小值
func FindMin() *Node {
	current := root
	minNode := current
	for ; current != nil; {
		minNode = current
		current = current.LeftChild
	}
	return minNode
}

//删除指定节点
func RemoverTree(key int) bool {
	current := root
	parent := root
	isLeftChild := false
	for ; current.Item != key; {
		parent = current
		if current.Item > key {
			isLeftChild = true
			current = current.LeftChild
		} else {
			isLeftChild = false
			current = current.RightChild
		}
		if current == nil {
			return false
		}
	}
	if current.LeftChild == nil && current.RightChild == nil {
		if current == root {
			root = nil
		} else if isLeftChild {
			parent.LeftChild = nil
		} else {
			parent.RightChild = nil
		}
		return true
	} else if current.LeftChild == nil && current.RightChild != nil {
		if current == root {
			root = current.RightChild
		} else if isLeftChild {
			parent.LeftChild = current.RightChild
		} else {
			parent.RightChild = current.RightChild
		}
		return true
	} else if current.LeftChild != nil && current.RightChild == nil {
		if current == root {
			root = current.LeftChild
		} else if isLeftChild {
			parent.LeftChild = current.LeftChild
		} else {
			parent.RightChild = current.LeftChild
		}
		return true
	} else {
		successor := getSuccessor(current)
		if current == root {
			successor = root
		} else if isLeftChild {
			parent.LeftChild = successor
		} else {
			parent.RightChild = successor
		}
		successor.LeftChild = current.LeftChild
	}
	return false
}

func getSuccessor(delNode *Node) *Node {
	successorParent := delNode
	successor := delNode
	current := delNode.RightChild
	for ; current != nil; {
		successorParent = successor
		successor = current
		current = current.LeftChild
	}
	if successor != delNode.RightChild {
		successorParent.LeftChild = successor.RightChild
		successor.RightChild = delNode.RightChild
	}
	return successor
}

func main() {
	Insert(50)
	Insert(20)
	Insert(80)
	Insert(10)
	Insert(30)
	Insert(60)
	Insert(90)
	Insert(25)
	Insert(85)
	Insert(100)
	PrintTree(root, 0, "root", 10)
	RemoverTree(10)
	RemoverTree(30)
	RemoverTree(80)
	fmt.Println("--------------------------------")
	PrintTree(root, 0, "root", 10)
	fmt.Println("--------------------------------")
	fmt.Println("最大值:", FindMax().Item)
	fmt.Println("最小值:", FindMin().Item)
}

效果图: