目录
题目:将有序数组转换为二叉搜索树
题目链接:LeetCode-108. 将有序数组转换为二叉搜索树
思路分析:数组中间数作为根节点
二叉搜索树特点:根左侧所有子节点值<根节点值<根右侧所有子节点值。
升序排列的数组,其中间数可作为根节点。
然后对数组范围缩小至:左边一半,右边一半。
这就构成了递归。
Go代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func sortedArrayToBST(nums []int) *TreeNode {
length := len(nums)
if length == 0 {
return nil
}
left, right := 0, length-1
mid := (right-left)>>1+left
return &TreeNode{
Val: nums[mid],
Left: sortedArrayToBST(nums[:mid]),
Right: sortedArrayToBST(nums[mid+1:]),
}
}
题目:二叉搜索树中的插入操作
题目链接:LeetCode-701. 二叉搜索树中的插入操作
思路分析:二叉搜索树的插入总是存在一个不需要调整树结构,就能插入新节点的位置
- 二叉搜索树特点:根左侧所有子节点值<根节点值<根右侧所有子节点值。
- 二叉搜索树特点:对于普通二叉搜索树的插入,在不考虑平衡性问题时,总是存在一个不需要调整树结构,就能插入新节点的位置(本质是将新节点插入到叶子节点,而不会破坏整个树的有序性质)。
- 根据插入值val与root.Val比较大小,得知其应该插入在root的左侧还是右侧。
- 递归确定位置之后,赋值为新节点即可。
Go代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func insertIntoBST(root *TreeNode, val int) *TreeNode {
if root == nil {
root = &TreeNode{Val:val}
return root
}
if root.Val > val {
root.Left = insertIntoBST(root.Left, val)
} else {
root.Right = insertIntoBST(root.Right, val)
}
return root
}
题目:删除二叉搜索树中的节点
题目链接:LeetCode-450. 删除二叉搜索树中的节点
思路分析:分析删除节点的子树的4种情况
- 二叉搜索树特点:根左侧所有子节点值<根节点值<根右侧所有子节点值。
- 根据删除值val与root.Val比较大小,得知其应该在root的左侧还是右侧,递归直到找到该节点。
- 该节点的子树可能的4种情况:
- 该节点是叶子节点:返回nil 给其父节点即可。
- 该节点只有左子树:返回其左子树给其父节点即可。
- 该节点只有右子树:返回其右子树给其父节点即可。
- 该节点左右子树都存在:(有两种做法)
1. 返回其左子树给其父节点:在返回之前,将其右子树接到其左子树的最右子节点的Right上。
2. 返回其右子树给其父节点:在返回之前,将其左子树接到其右子树的最左子节点的Left上。
Go代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func deleteNode(root *TreeNode, key int) *TreeNode {
if root == nil {
return root
}
if root.Val > key { // 删除节点在左子树
root.Left = deleteNode(root.Left, key)
} else if root.Val < key { // 删除节点在右子树
root.Right = deleteNode(root.Right, key)
} else {
// 删除的节点:只有左子树 或右子树 或都没有
if root.Left == nil || root.Right == nil {
if root.Left != nil {
return root.Left
}
return root.Right
} else { // 删除的节点存在左右子树
cur := root.Left
// 目前root.Left和root.Right是同一级的,这里如果返回root.Left,就需要把root.Right接到root.Left的右侧最大子节点上
// 反之如果要返回root.Right,就需要把root.Left接到root.Right的左侧最小子节点上
for cur.Right != nil {
cur = cur.Right
}
cur.Right = root.Right
return root.Left
}
}
return root
}