二叉树经典练习题合集2(Java实现)

目录

二叉树的最近公共祖先

二叉搜索树与双向链表 

从前序和中序遍历序列构造二叉树 

根据二叉树创建字符串 


 

 本篇所有的代码已更新至码云仓库中,代码仓库地址:我的代码仓库

二叉树的最近公共祖先

题目链接二叉树的最近公共祖先

题目描述:给定一棵二叉树,找到该树中两个指定结点的公共祖先. 

例如

 解题思路

1.首先判断该树是否为空,若为空直接返回null

2.判断给定的两个结点是否有为根结点的,若有,则直接返回根结点,根结点即这两个结点的公共祖先

3.分别递归遍历左子树和右子树,寻找其公共祖先,递归结束后判断保存的leftTree和rightTree:

①若leftTree和rightTree都为空,则其公共祖先为根节点;

②若leftTree为空,则p和q的公共祖先为rightTree;

③若rightTree为空,则p和q的公共祖先为leftTree.

具体实现代码如下

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) {
            return null;
        }
        if(p == root || q == root) {
            return root;
        }

        TreeNode leftTree = lowestCommonAncestor(root.left,p,q);
        TreeNode rightTree = lowestCommonAncestor(root.right,p,q);

        if(leftTree != null && rightTree != null) {
            return root;
        }
        if(leftTree != null) {
            return leftTree;
        }else {
            return rightTree;
        }
    }

二叉搜索树与双向链表 

题目链接: 二叉搜索树与双向链表

题目描述: 输入一棵二叉搜索树,将二叉搜索树转换成一个双向的排序链表,具体如下图所示.

知识点回顾:什么是二叉搜索树?

二叉搜索树或是一棵空树,或是一棵具有如下性质的二叉树:若它的左子树不为空,则左子树上所有结点的值小于它的根结点值;若它的右子树不为空,则右子树上所有结点的值大于它的根结点值;它的左右子树分别也为二叉排序树.

解题思路

为了方便代码的编写,采用了两个方法(Convert和ConvertChild方法)来实现转换操作

1、Convert方法的作用:

①判断该树是否为空,若为空直接返回null;

②在二叉搜索完成转换后寻找并返回双向链表的头结点.

2、ConvertChild方法的作用:

利用递归来实现二叉树对于双向链表的转换,转换完成后二叉搜索树的left代表着双向链表的前驱,right代表后驱.

①首先全局初始化一个结点prev用来完成每个的前驱链接;

②递归找到最后一个左子树,从该结点开始转换,转换的顺序依次为左、根、右;

具体的实现由递归完成,在方法中只思考如何转换:

无论是哪个结点,要进行转换必须将其left指向prev,再将prev.right指向该结点,具体实现思路可以了解下列代码

具体代码实现如下: 

    public TreeNode prev = null;
    public void ConvertChild(TreeNode pCur) {
        if(pCur == null) {
            return;
        }
        ConvertChild(pCur.left);
        pCur.left = prev;
        if(prev != null) {
            prev.right = pCur;
        }
        prev = pCur;
        ConvertChild(pCur.right);
    }
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null) {
            return null;
        }
        ConvertChild(pRootOfTree);
        TreeNode head = pRootOfTree;
        while(head.left != null) {
            head = head.left;
        }
        return head;
    }

从前序和中序遍历序列构造二叉树 

题目链接从前序和中序遍历遍历序列构造二叉树

题目描述: 给定两个整数数组preorder和inorder,其中preorder表示的二叉树的先序遍历,inorder表示的二叉树的先序遍历,请构造二叉树并返回其根结点.

例如 

 

解题思路: 

首先了解前序遍历的顺序:根->左->右,中序遍历的顺序:左->根->右,根据两种遍历的思想初步确定实现思想:根据分治思想来解决该题

① 根据前序遍历可以知道根结点就是给定数组的第一个元素preorder[0],然后根据中序遍历在inorder数组中找到值等于preorder[0]的位置,该位置的前半部分即为左子树,右半部分为右子树;

② 重复“①”操作直到遍历完.

具体代码实现如下: 

    public int prevIndex = 0;
    public int findIndex(int[] preorder,int[] inorder,int begin,int end) {
        for(int i = begin; i<= end; i++) {
            if(inorder[i] == preorder[prevIndex]) {
                return i;
            }
        }
        return -1;
    }
    public TreeNode buildTreeChild(int[] preorder,int[] inorder,int begin,int end) {
        if(begin > end) {
            return null;
        }
        TreeNode root = new TreeNode(preorder[prevIndex]);
        int index = findIndex(preorder,inorder,begin,end);
        prevIndex++;
        root.left = buildTreeChild(preorder,inorder,begin,index-1);
        root.right = buildTreeChild(preorder,inorder,index+1,end);
        return root;
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return buildTreeChild(preorder,inorder,0,inorder.length-1);
    }

根据二叉树创建字符串 

题目链接根据二叉树创建字符串

题目描述:你需要采取前序遍历的方式,将一棵二叉树转换成一个由括号和整数构成的字符串。

空结点由一对空括号"()"表示. 

例如

 

解题思路: 

利用StringBuilder类来完成二叉树对字符串的转换,在转换完成后将其转换为String类型返回.

根据题意需要完成下列判断:

1、根据前序遍历顺序:根左右,首先判断根,若root不为null,首先将根结点利用append方法转换成字符串;

2、其次判断其左子树:

①若根结点左子树不为空,根据题意先加入'(',之后递归遍历其左子树,遍历完成后加上')';

②若根结点左子树为空:

如果其右子树也为空,则直接返回;若不为空,则根据题意加上'()',之后继续遍历其右子树.

3、最后判断其右子树:

①若右子树为空,直接返回;

②若不为空,则首先加入'(',之后对其右子树依次进行遍历,最终加上')'.

经过递归上述过程,即可实现二叉树对于字符串的转换

具体代码实现如下: 

    public void tree2strChild(TreeNode t, StringBuilder sb) {
        if(t == null) {
            return;
        }
        sb.append(t.val);
        if(t.left != null) {
            sb.append("(");
            tree2strChild(t.left,sb);
            sb.append(")");
        }else {
            if(t.right == null) {
                return;
            }else {
                sb.append("()");
            }
        }
        if(t.right == null) {
            return;
        }else {
            sb.append("(");
            tree2strChild(t.right,sb);
            sb.append(")");
        }
    }
    public String tree2str(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        if(root == null) {
            return sb.toString();
        }
        tree2strChild(root, sb);
        return new String(sb);
    }

 

 

(1)非递归定义 树(tree)是由n(n≥0)个结点组成的有限集合。n=0的树称为空树;n>0的树T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作树的根(root)结点。 ② 除结点外n0 , 其余的每一个结点都有且仅有一个直接前驱结点;有零个或多个直接后继结点。 (2)递归定义 一颗大树分成几个大的分枝,每个大分枝再分成几个小分枝,小分枝再分成更小的分枝,… ,每个分枝也都是一颗树,由此我们可以给出树的递归定义。 树(tree)是由n(n≥0)个结点组成的有限集合。n=0的树称为空树;n>0的树T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作树的根(root)结点。 ② 除根结点之外的其他结点分为m(m≥0)个互不相交的集合T0,T1,…,Tm-1,其中每个集合Ti(0≤i<m)本身又是一棵树,称为根的子树(subtree)。 2、掌握树的各种术语: (1) 父母、孩子与兄弟结点 (2) 度 (3) 结点层次、树的高度 (4) 边、路径 (5) 无序树、有序树 (6) 森林 3、二叉树的定义 二叉树(binary tree)是由n(n≥0)个结点组成的有限集合,此集合或者为空,或者由一个根结点加上两棵分别称为左、右子树的,互不相交的二叉树组成。 二叉树可以为空集,因此根可以有空的左子树或者右子树,亦或者左、右子树皆为空。 4、掌握二叉树的五个性质 5、二叉树的二叉链表存储。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li_yizYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值