首页 > 其他分享 >Day20 二叉树Part7 二叉搜索树的增删查

Day20 二叉树Part7 二叉搜索树的增删查

时间:2024-08-05 14:30:45浏览次数:14  
标签:node return val self Day20 value 二叉树 Part7 节点

目录

任务

235. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

思路

由于是二叉搜索树,所以可以利用其性质进行查找,即,只有在p和q的值的范围内的才是其祖先,并且由于遍历的递归序,当第一次遇到符合条件节点的时候,就是其最近公共祖先。
如果不满足条件时,递归的向其子树寻找,然后向上层返回。

  • 局部: 是否满足节点的数值条件
  • 子树递归: 根据值的大小和BST的性质向下(左或右)寻找
  • 返回值: 向上层返回当前的信息,告诉上层我找到了,节点是XXX。
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        return self.dfs(root,p,q)
    
    def dfs(self,node,p,q):
        if not node: return None
        if node.val > p.val and node.val > q.val:
            return self.dfs(node.left,p,q)
        elif node.val < p.val and node.val < q.val:
            return self.dfs(node.right,p,q)
        else: return node

701. 二叉搜索树中的插入操作

思路

插入的初步也是找到插入的位置,即查找。根据对BST的分析,任意数值都可以插入成为叶子节点以满足题意,这样的作法最简单,不需要调整树的结构。
个人觉得无返回值的逻辑比较好理解,就是处理上只有递没有归的过程,一直告诉下层你去合适的位置插入节点,直到到达目标位置,之后归的过程全是空,即无返回值,因为到达叶子节点做完插入这件事后,归的过程父节点不需要子节点的信息了(虽然这个过程是一定会进行的)

  • 边界条件:如果是空树,直接构造并返回新的节点。
  • 边界条件:到达插入位置的父节点后,将新节点插入
  • 子树递归: 根据BST性质,向左或者向右遍历,直到到达插入位置的父节点
class Solution:
    def __init__(self):
        self.pre = None
    def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        if not root:
            return TreeNode(val)
        self.dfs(root,val)
        return root
    def dfs(self,node,value):
        if not node:
            newNode = TreeNode(value)
            if self.pre.val > value:
                self.pre.left = newNode
            else:
                self.pre.right = newNode
        
        else:
            self.pre = node
            if value < node.val:
                self.dfs(node.left,value)
            elif value > node.val:
                self.dfs(node.right,value)
        

而代码随想录的有返回值的思路有点不好理解,细细分析后也比较方便,且写法上比较简洁,这里给出思路分析和代码

  • 如果是空树,或者说找到插入位置,直接构造并返回新的节点。
  • 子树递归:根据值的大小向左右层递归,并修改当前层的左或右指针(实际只有到达最后一层之前才实际接上了新节点,而其他节点的操作和覆盖相同(比如node.left = 下一层左边返回的node,但是这个语句进行后和不进行是一样的,等于啥都没做,只是递归的归的过程自然进行,之所以还需要也是为了接新节点的那次链接)
  • 返回值: 返回自身节点,是为了子树归的过程中,赋值给上层的left或者right
class Solution:
    def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        return self.dfs(root,val)
        
    def dfs(self,node,value):
        if not node:
            newNode = TreeNode(value)
            return newNode
        
        if value < node.val:
            node.left =  self.dfs(node.left,value)
            return node
        elif value > node.val:
            node.right = self.dfs(node.right,value)
            return node

450. 删除二叉搜索树中的节点

思路

逻辑是找到并删除。

  • 找的过程用递归中递的逻辑,且需要接底层返回的节点,归的时候是向上返回删除后的当前节点。
  • base case比较复杂,分为5种情况,代码中有详细注释
class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        return self.dfs(root,key)
        
    def dfs(self,node,value):
        if not node: return None # 情况1,没找到
        if node.val == value:
            if not node.left and not node.right:  #情况2,删除节点为叶子节点
                return None
            if not node.left and node.right:  #情况3,删除节点没有左孩子
                return node.right
            if node.left and not node.right:  #情况4,删除节点没有右孩子
                return node.left
            else: #情况5,删除的节点有左右孩子,则将其左子树放到右子树最左,然后用右孩子替代删除节点
                cur = node.right
                while cur.left:
                    cur = cur.left
                cur.left = node.left
                return node.right

        if value < node.val: 
            node.left = self.dfs(node.left,value)
        else:
            node.right = self.dfs(node.right,value)    
        return node

心得体会

学习了BST的增删查,总体思路为由BST性质一路向下找到对应的节点,进行操作,然后返回上层合法的节点并用上层的指针域链接。

标签:node,return,val,self,Day20,value,二叉树,Part7,节点
From: https://www.cnblogs.com/haohaoscnblogs/p/18343139

相关文章

  • 代码随想录day20 || 235 二叉搜索树最近公共祖先,701 二叉搜索树插入,450,二叉搜索树删除
    235二叉搜索树最近公共祖先unclowestCommonAncestor(root,p,q*TreeNode)*TreeNode{ //本题相较于普通二叉树寻找最近公共祖先加了题设条件二叉搜索树,所以使用二叉搜索树特性 //如果root大于两个目标节点,那么目标都在root左子树 //如果root小于两个目标节点,那么目......
  • 算法力扣刷题总结篇 ——【五】二叉树章节
    前言从记录三十五【二叉树基础和递归遍历】到记录六十二【538.把二叉搜索树转换为累加树】28篇文章都是二叉树的章节。所以总结的任务量有点大啊。但还是要做的。完成之后,开启新章节……继续。一、题目回顾1-5:遍历方式模版题。6-14:确定遍历顺序。后序居多——先统......
  • 数据结构之《二叉树》(中)
    在数据结构之《二叉树》(上)中学习了树的相关概念,还了解的树中的二叉树的顺序结构和链式结构,在本篇中我们将重点学习二叉树中的堆的相关概念与性质,同时试着实现堆中的相关方法,一起加油吧!1.实现顺序结构二叉树在实现顺序结构的二叉树中通常把堆使用顺序结构的数组来存储,因......
  • day018二叉树
    530.二叉树的最小绝对差给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。差值是一个正数,其数值等于两值之差的绝对值。 思路:此题与昨天的验证二叉搜索树很像,同样是中序遍历将二叉树节点按照顺序加入到动态数组中,随后遍历动态数组,维护一......
  • day014(二叉树章节)+北境互娱游戏开发一面
    222.完全二叉树节点的个数给你一棵完全二叉树的根节点root,求出该树的节点个数。完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第h层,则该层包含1~ 2h 个......
  • 二叉树链式结构代码讲解与实现
    本片将续之前的文章二叉树的概念进行二叉树基本操作的实现,二叉树oj题将在下篇文章讲解。目录a.创建二叉树代码:一、二叉树的遍历1.1前序、中序以及后序遍历代码:如图:(前序遍历递归图解)测试代码:二、节点个数以及高度2.1 二叉树节点个数思想:要求二叉树的总节点个数,左......
  • 【数据结构】二叉树和堆
     一、二叉树1.二叉树的基本概念在C语言中,二叉树是一种基础的数据结构,它由节点组成,每个节点包含数据元素以及指向其他节点的指针。下面是二叉树的基本概念以及如何在C语言中表示和操作它。节点(Node):二叉树的每个元素称为节点,每个节点都有一个数据域和两个指针域,通常称为左指......
  • 代码随想录算法训练营Day18 | Leetcode 530 二叉搜索树的最小绝对差 Leetcode 236 二
    前言今天有一道题目没写,二叉搜索树中的众数,有点太难理解了,先放一放。Leetcode530二叉搜索树的最小绝对差题目链接:530.二叉搜索树的最小绝对差-力扣(LeetCode)代码随想录题解:代码随想录(programmercarl.com)思路:二叉搜索树的性质是中序遍历为升序的,所以我们想找最小绝......
  • Day18 二叉树Part6
    目录任务530.二叉搜索树的最小绝对差思路501.二叉搜索树中的众数思路236.二叉树的最近公共祖先思路心得体会任务530.二叉搜索树的最小绝对差给你一个二叉搜索树的根节点root,返回树中任意两不同节点值之间的最小差值。差值是一个正数,其数值等于两值之差的绝对值。思路......
  • 先(后)序遍历确定唯一二叉树
    在二叉树的先序遍历或后序遍历序列中,如果我们记录了空节点的位置(通常用特殊符号如'#'表示),就足以唯一确定一棵二叉树的结构。这种方法的关键在于,记录空节点的位置能够帮助我们在遍历序列中准确地还原出树中节点的结构信息。因此,只要给出了先序遍历或后序遍历序列以及空节点的位置,......