Java——二叉树的最近公共祖先及二叉搜索树介绍

这篇具有很好参考价值的文章主要介绍了Java——二叉树的最近公共祖先及二叉搜索树介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

二叉树的最近公共祖先

题目 

思路一:如果给定的是一颗二叉搜索树,

思路二:假设是孩子双亲表示法

 二叉搜索树

定义Node类

查找

删除

插入


二叉树的最近公共祖先

题目 

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

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

Java——二叉树的最近公共祖先及二叉搜索树介绍

提示:

树中节点数目在范围 [2, 105] 内。
-109 <= Node.val <= 109
所有 Node.val 互不相同 。
p != q
p 和 q 均存在于给定的二叉树中

思路一:如果给定的是一颗二叉搜索树,

二叉搜索树:中序遍历的大小是有序的,根节点的左树都比根节点的小,根节点的右树都比根节点大。

 Java——二叉树的最近公共祖先及二叉搜索树介绍

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //先根据二叉搜索树来写
        if(root==null) return null;
        if(root==p||root==q) return root;
        TreeNode leftT=lowestCommonAncestor(root.left,p,q);
        TreeNode rightT=lowestCommonAncestor(root.right,p,q);
        if(leftT!=null&&rightT!=null){
            return root;
        }else if(leftT!=null){
            return leftT;
        }else{
            return rightT;

        }
        
    }
}

思路二:假设是孩子双亲表示法

就相当于链表求交点,但是我们的表示中没有双亲结点,因此我们引入两个栈。

Java——二叉树的最近公共祖先及二叉搜索树介绍1.用两个栈 存储root->q,root->p的路径;

2.求栈的大小;

3.让栈中多的元素出差值个元素;

4.开始出栈,直到栈顶元素相同,就是公共祖先;

如何去找到从根节点到一个指定节点的路径? 文章来源地址https://www.toymoban.com/news/detail-402102.html

class Solution {
    //root根结点,node:指定的节点,stack:存放根节点到指定节点的路径
    public boolean getPath(TreeNode root,TreeNode node ,Stack<TreeNode> stack){
        if(root==null||node==null) return false;
        stack.push(root);
        if(node==root) return true;
        boolean flg=getPath(root.left,node,stack);
        if(flg==true) return true;//找到啦
      flg=getPath(root.right,node,stack);
        if(flg==true) return true;//找到啦
        stack.pop();
        return false;

    }
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null) return null;
        Stack<TreeNode> stack1=new Stack<>();
        getPath(root,p,stack1);
        Stack<TreeNode> stack2=new Stack<>();
        getPath(root,q,stack2);
        int size1=stack1.size();
        int size2=stack2.size();
        if(size1>size2){
            int size=size1-size2;
            while(size!=0){
                stack1.pop();
                size--;
            }
            while(!stack1.isEmpty()&&!stack2.isEmpty()){
                //直接判断地址
                if(stack1.peek()==stack2.peek()){
                    return stack1.pop();
                }else{
                    stack1.pop();
                    stack2.pop();
                }
            }

        }else{
            int size=size2-size1;
            while(size!=0){
                stack2.pop();
                size--;
            }
            while(!stack1.isEmpty()&&!stack2.isEmpty()){
                //直接判断地址
                if(stack1.peek()==stack2.peek()){
                    return stack2.pop();
                }else{
                    stack1.pop();
                    stack2.pop();
                }
            }
        }
        return null;



    }
}

 二叉搜索树

是空树或者:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树

定义Node类

class Node{
    public int val;
    public Node left;
    public Node right;
    public Node(int val){
        this.val=val;
    }
}

查找

  public Node root=null;
    public Node search(int key){
        Node cur = root;
        if(cur.val<key){
            cur = cur.right;
        }else if(cur.val>key){
            cur = cur.left;
        }else{
            return cur;
        }
        return null;
    }

删除

设待删除结点为 cur, 待删除结点的双亲结点为 parent
1. cur.left == null
1. cur root ,则 root = cur.right
2. cur 不是 root cur parent.left ,则 parent.left = cur.right
3. cur 不是 root cur parent.right ,则 parent.right = cur.right
2. cur.right == null
1. cur root ,则 root = cur.left
2. cur 不是 root cur parent.left ,则 parent.left = cur.left
3. cur 不是 root cur parent.right ,则 parent.right = cur.left
3. cur.left != null && cur.right != null
1. 需要使用 替换法 进行删除,即在它的右子树中寻找中序下的第一个结点 ( 关键码最小 ) ,用它的值填补到被
删除节点中,再来处理该结点的删除问题
Java——二叉树的最近公共祖先及二叉搜索树介绍
   //要删除节点,你需要知道这个节点的父节点
    //当要删除的节点的左节点为空
    //一般删除节点都是删除叶子节点

    public void f(Node cur,Node parent){
        if(cur.left==null){//当删除的节点左边没有节点
            if(cur==root){
                root=cur.right;
            }else if(cur==parent.left){
                parent.left=cur.right;

            }else{
                parent.right=cur.right;

            }
        }else if(cur.right==null){
            if(cur==root){
                root=cur.left;
            }else if(cur==parent.left){
                parent.left=cur.left;
            }else{
                parent.right=cur.left;
            }
        }else{//左右节点都不是空
            //相当于在右树中找一个较小值换到那个位置
            //或者就是在左树中找较大值
            //
            Node targetParent=cur;
            Node target=cur.right;
            while(target.left!=null){
                targetParent=target;
                target=target.left;
            }
            cur.val=target.val;
            if(target==targetParent.left){
                targetParent.left=target.right;
            }else{
                targetParent.right=target.right;
            }
        }


    }
    public void remove(int key){
        Node cur=root;
        Node parent=null;
        while(cur!=null){
            if(cur.val==key){
                f(cur,parent);
                break;
            }else if(cur.val<key){
                parent=cur;
                cur=cur.right;
            }else{
                parent=cur;
                cur=cur.left;
            }

        }
    }

插入

   //二叉搜索树插入的数据一定是在叶子节点
    //1.cur,parent来找到val需要存储的位置
    //2.parent.val比较大小,确定格式在左边还是右边进行插入
    public  boolean insert(int val){
        if(root == null){
            root = new Node(val);
            return true;

        }
        Node cur = root;
        Node parent = null;
        //找到parent的位置
        while(cur!=null){
            if(cur.val<val){
                parent=cur;
                cur=cur.right;
            }else if(cur.val==val){//bu
                return false;
            }else{
                parent=cur;
                cur=cur.left;
            }
        }
        //找到对应位置开始插入
        Node node=new Node(val);
        if(parent.val<val){
            parent.right=node;
        }else{
            parent.left=node;
        }
        return true;

    }

到了这里,关于Java——二叉树的最近公共祖先及二叉搜索树介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包