• 【LeetCode】删除二叉搜索树中的节点


    删除二叉搜索树中的节点

    题目链接:https://leetcode-cn.com/problems/delete-node-in-a-bst/

    题目大意:删除指定key的节点,返回root

    分析:树是二叉搜索树,要求返回后仍然保持搜索树的位置

    二叉搜索树:根节点值大于左孩子值,根节点值小于右孩子值

    根据待删除节点的情况,我们可以采取不同的措施

    • 如果目标节点大于当前节点值,则去右子树中删除;

    • 如果目标节点小于当前节点值,则去左子树中删除;

    • 如果目标节点就是当前节点,分为以下三种情况:

      • 其无左子:其右子顶替其位置,删除了该节点;
      • 其无右子:其左子顶替其位置,删除了该节点;
      • 其左右子节点都有:其左子树转移到其右子树的最左节点的左子树上,然后右子树顶替其位置,由此删除了该节点。

      第三种情况如图:

    • 时间复杂度:O(H),H是树的高度,寻找目标节点最坏情况需要O(H),删除操作最坏情况也需要O(H);
    • 空间复杂度:O(H),递归栈的深度最坏情况为树的高度;
    
    func deleteNode(root *TreeNode, key int) *TreeNode {
    	if root==nil{
    		return nil
    	}
    
    	if key>root.Val{
    		// 目标值大于当前值,则去当前节点的右子树中删除
    		root.Right=deleteNode(root.Right,key)
    	}else if key<root.Val{
    		// 目标值小于当前值,则去当前节点的左子树中删除
    		root.Left=deleteNode(root.Left,key)
    	}else if key==root.Val{
    		// 目标节点等于当前值,分析当前节点的左右孩子情况,采取不同策略
    
    		if root.Left==nil{
    			// 待删除节点的左孩子为空,则右孩子顶替待删除节点位置
    			root=root.Right
    		}else if root.Right==nil {
    			// 待删除节点的右孩子为空,则左孩子顶替待删除节点位置
    			root=root.Left
    		}else if root.Right!=nil&&root.Left!=nil {
    			// 待删除节点的左右孩子都不为空,现在处理其左右孩子
    
    			// 第一步:寻找待删除root节点的右子树的最左节点node
    			node:=root.Right
    			for node.Left!=nil{
    				node=node.Left
    			}
    
    			// 第二步:root左子树转移到node的左子树上,仍然保存搜索树性质
    			node.Left=root.Left
    
    			// 第三步:root的右子树顶替root位置
    			root=root.Right
    
    		}
    	}
    	return root
    }
    
  • 相关阅读:
    pychram 2018-01 安装pyQT5报错
    pyqt 8行内就可以跑一个浏览器
    sql server无log ldf日志文件附件mdf数据库重新生成ldf日志文件
    解决Specifying a namespace in include()withou providing an app_name
    Java 连接池的工作原理(转)
    使用from __future__ import unicode_literals时要注意的问题
    详细介绍Redis的几种数据结构以及使用注意事项(转)
    再谈Redis应用场景(转)
    Redis的LRU机制(转)
    深入理解Redis主键失效原理及实现机制(转)
  • 原文地址:https://www.cnblogs.com/yinbiao/p/16112775.html
Copyright © 2020-2023  润新知