赞
踩
注:二叉树的中序遍历结果是一个有序数列
给定一个数组,把它变为二叉搜索树
先定义二叉树结构:
- type LinkNode struct{
- Val int
- Left *LinkNode
- Right *LinkNode
- }
注:二叉排序树最好情况为:完全二叉树 O(logn)
最坏情况为:退化为单链表O(n)
二叉树查找:
- // 查找
- // 类似二分查找的树化
- func (root *LinkNode) SearchTree(targer int) *LinkNode {
- if root == nil {
- return nil
- }
- for root != nil {
- if root.Val > targer {
- root = root.Left
- } else if root.Val < targer {
- root = root.Right
- } else {
- return root
- }
- }
- return nil
- }
- // 插入数据
- // 如果插入的元素已存在,直接返回false
- // 需要随时记录父节点的位置
- func (root *LinkNode) insertTree(targer int) bool {
- node := &LinkNode{Val: targer}
- if root == nil {
- root.Val = targer
- }
- var parent *LinkNode
- cur := root
- for cur != nil {
- if cur.Val == targer { // 有重复元素则返回
- return false
- } else if cur.Val > targer {
- parent = cur // 保留当前节点
- cur = cur.Left
- } else {
- parent = cur
- cur = cur.Right
- }
- }
- if parent.Val > targer {
- parent.Left = node
- } else {
- parent.Right = node
- }
- return true
- }
有两种情况
解决:
第一种情况直接让左/右孩子直接代替被删除节点
第二种情况需要进行 旋转 处理!!!
- func (root *LinkNode) remove(targer int) bool {
- if root == nil { // 树为空,不存在要删除的节点
- return false
- }
-
- var parent *LinkNode // 被删除节点的父节点
- cur := root // 复制一份
- for cur != nil {
- if cur.Val == targer {
- removeKey(parent, cur)
- return true
- } else if cur.Val > targer {
- parent = cur
- cur = cur.Left
- } else {
- parent = cur
- cur = cur.Right
- }
- }
- return false
- }
-
- // 处理三种情况(其中两种类似)
- func (root *LinkNode) removeKey(parent *LinkNode, cur *LinkNode) {
- if cur.Left == nil { // 被刪除节点左孩子为空
- if cur == root { // 被删除节点为 根节点
- root = root.Right
- } else if cur == parent.Left { // 被删除节点 在父节点的左边
- parent.Left = cur.Right
- } else { // 被删除节点 在父节点的右边
- parent.Right = cur.Right
- }
- } else if cur.Right == nil {
- if cur == root {
- root = root.Left
- } else if cur == parent.Left {
- parent.Left = cur.Left
- } else {
- parent.Right = cur.Left
- }
- } else { // 处理最复杂的情况。被删除节点左右孩子都不为空
- // 一般取被删除节点的右孩子的最小值,替换被删除节点
- parentNode := cur // 保存被删除的节点
- minNode := cur.Right // 获取被删除节点的右节点(被删除节点的右孩子)
- for parentNode != nil {
- parentNode = minNode
- minNode = minNode.Left
- }
- // 找到合适的节点(右孩子的最小值)
- cur.Val = minNode.Val
- if parentNode.Left == minNode {
- parentNode.Left = minNode.Right
- } else {
- parentNode.Right = minNode.Right // 用于处理右孩子为单链表结构
- }
-
- }
- }
验证:中序遍历
- // 中序遍历 用于验证是否成功
- func (root *LinkNode) midPrint() []int {
- var res []int
- var dfs func(*LinkNode)
- dfs = func(root *LinkNode) {
- if root == nil {
- return
- }
-
- if root.Left != nil {
- dfs(root.Left)
- }
- res = append(res, root.Val)
- if root.Right != nil {
- dfs(root.Right)
- }
- }
- dfs(root)
- return res
- }
-
- func main() {
- // 构建二叉树
- root := &LinkNode{Val: 4}
- root2 := &LinkNode{Val: 2}
- root3 := &LinkNode{Val: 6}
- root4 := &LinkNode{Val: 1}
- root5 := &LinkNode{Val: 5}
- root6 := &LinkNode{Val: 7}
- root.Left = root2
- root.Right = root3
- root2.Left = root4
- root3.Left = root5
- root3.Right = root6
-
- fmt.Println(root.SearchTree(8)) // 查找元素 8
- res := root.midPrint()
- fmt.Println(res) // 打印中序遍历的二叉树
- fmt.Println(root.insertTree(10)) // 插入元素10
- fmt.Println(root.remove(4)) // 删除元素4(根节点)
- res = root.midPrint()
- fmt.Println(res) // 打印中序遍历的二叉树
- }
结果:
<nil>
[1 2 4 5 6 7]
true // 插入成功
true // 删除成功
[1 2 5 6 7 10]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。