C C++最新数据结构java版之二叉树(部分offer面试题篇)_二叉树java面试题,附C C++面经

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

代码如下:

//求第K层结点的个数
 public int getKLevelNodeCount(int k){
    return getKLevelNodeCount(root, k);
    }
     // 获取第K层结点的个数
    private int getKLevelNodeCount(BTNode root,int k){
          if(root==null || k<=0){
             return 0;
          }
          if(k==1){
              return 1;
          }
          return getKLevelNodeCount(root.left, k-1)+getKLevelNodeCount(root.right, k-1);

    }

5.获取二叉树的高度

思路分析:

代码如下:

 // 获取二叉树的高度(时间复杂度为O(n))
    int getHeight(BTNode root){
        if(root==null){
            return 0;
        }
       int leftHeight=getHeight(root.left);
        int rightHeight=getHeight(root.right);
//此处用的是三目运算符求取两者中的较大值
        return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
    }
6.检测值为value的元素是否存在

解题思路:

代码如下 :

// 检测值为value的元素是否存在
    boolean find(BTNode root, int val) {
        if (root == null) {
            return false;
        } else if (root.val == val) {
            return true;
        }
        if (find(root.left, val) || find(root.right, val)) {
            return true;
        }
        return false;
    }
7.判断一棵树是不是完全二叉树

解题思路:

代码如下:

  boolean isCompleteTree(BTNode root){
        if(root == null) return true;
        Queue<BTNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            BTNode cur = queue.poll();
            if(cur != null) {
                queue.offer(cur.left);
                queue.offer(cur.right);
            }else {
                break;
            }
        }
//第二个while循环实质上就是在cur=null的基础上来判断实现的,若是整个为空即null 则true;反之为false
        while (!queue.isEmpty()) {
            BTNode top = queue.peek();
            if(top != null) {
                return false;
            }
            queue.poll();
        }
        return true;
    }
1. 检查两颗树是否相同

100. 相同的树 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/same-tree/

解题思路:

要判断两棵树是否相同:

①数的结构相同

②相应位置的结点对应的数值相同

代码如下:

 public boolean isSameTree(TreeNode p, TreeNode q ){
        if(p == null && q != null || p != null && q == null) {
            return false;
        }
        if(p == null && q == null) {
            return true;
        }
        if(p.val != q.val) {
            return false;
        }
        //p != null && q!= null && p.val == q.val
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }
2. 另一颗树的子树

572. 另一棵树的子树 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/subtree-of-another-tree/

代码如下:

 public boolean isSubtree(TreeNode root, TreeNode subRoot) {
  if(root == null || subRoot == null) {
             return false;
         }
        //根节点和subroot是不是两颗相同的树
        if(isSameTree(root,subRoot)) {
            return true;
        }
        //subRoot是不是root的左子树
        if(isSubtree(root.left,subRoot)) {
            return true;
        }
        if(isSubtree(root.right,subRoot)) {
            return true;
        }
        return false;
}
}
3. 二叉树最大深度

104. 二叉树的最大深度 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

同二叉树基本操作的5题,请参考此篇博客上方

4. 判断一颗二叉树是否是平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/balanced-binary-tree/submissions/

解题思路:

class Solution {
   public int height (TreeNode root) {
        if(root == null) {return 0;}
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        return (leftHeight > rightHeight) ?
                (leftHeight+1) :(rightHeight+1);
    }

    /**
     时间复杂度:O(N^2)
     */
    public boolean isBalanced(TreeNode root) {
        if(root == null) return true;
        int left = height(root.left);
        int right = height(root.right);
        return Math.abs(left-right) <= 1 && isBalanced(root.left) && isBalanced(root.right);
    }
}
5. 对称二叉树

101. 对称二叉树 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/symmetric-tree/解题思路:

代码如下:

class Solution {
     public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        return isSymmetricChild(root.left,root.right);
    }
   public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {
       //第一种情况
       if(leftTree == null && rightTree == null) return true;
       //第二种情况
        if((leftTree == null && rightTree != null)||(leftTree != null && rightTree == null))               return false;
        //第三种情况
        if(leftTree.val != rightTree.val) return false;
        return isSymmetricChild(leftTree.left,rightTree.right) &&
                isSymmetricChild(leftTree.right,rightTree.left);
    }

6. 二叉树的构建及遍历牛客网链接icon-default.png?t=M0H8http:///www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking
7. 二叉树的分层遍历

102. 二叉树的层序遍历 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/binary-tree-level-order-traversal/

解题思路:

借助一个队列和一个临时变量cur来打印分层遍历

①讨论根是否为空的情况

②当队列不为空时,出队列中的队尾元素到cur中,并通过cur.val进行打印

③循环讨论子左右子树的情况,所以要用while进行循环

两类代码:

①普通代码:

  //打印层序遍历二叉树
  public void levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
//①判断树是否为空的情况
        if(root == null) return;
        queue.offer(root);
//②判断队列是否为空
        while (!queue.isEmpty()) {
            TreeNode cur = queue.poll();
            System.out.print(cur.val+" ");
            if(cur.left != null) {
                queue.offer(cur.left);
            }
            if(cur.right != null) {
                queue.offer(cur.right);
            }
        }
    }

②OJ上解题的代码:

解题思路:

代码如下:

//层序遍历访问打印元素
List<List<Integer>> ret = new ArrayList<>();
        if(root == null) return ret;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
//当前的结点个数size
            int size = queue.size();
            List<Integer> list = new ArrayList<>();
            while (size != 0) {
                TreeNode cur = queue.poll();
//将同层结点放在一个list中
                list.add(cur.val); 
                if(cur.left != null) {
                    queue.offer(cur.left);
                }
                if(cur.right != null) {
                    queue.offer(cur.right);
                }
                size--;//1 0
            }
//将所有一层link的结点放在同一个list中
            ret.add(list);
        }
//最后返回整个所需的ret
        return ret;
}
8. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

236. 二叉树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

解题思路:

思路①:由二叉搜索树的思想来设计二叉树的方法

若是二叉搜索树

详细思路:

1.rootp || rootq(p,q为结点)
此时的最近公共祖先是root
2.可能均在根的左边或者右边
①p.val<root.val && q.val<root.val(p,q均在root的左子树中)
最近公共祖先在左子树中


②p.val>root.val && q.val>root.val(p,q均在root的右子树中)
最近公共祖先在右子树中


3.最近的公共祖先就是root
①p.val>root.val && q.val<root.val(p在左子树中,q在右子树中)
②p.val<root.val && q.val>root.val(p在右子树中,q在左子树中)


 代码如下:

//二叉树的最近公共祖先
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null){
            return null;
        }if(root==p||root==q){
            return root;
        }
        TreeNode l=lowestCommonAncestor(root.left,p,q);
        TreeNode r=lowestCommonAncestor(root.right,p,q);
       if(l!=null && r!=null){
    return root;
}else if(l!=null){
    return l;
}else{
    return r;
}
        }
    }

思路②:

由孩子双亲表示法来求取

代码如下:

class Solution {
    //root:
    public boolean getPath(TreeNode root,TreeNode node,Stack<TreeNode>stack){
if(root==null || node==null){
return false;
}stack.push(root);
if(root==node){
    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 stack1.pop();
                }else{
                    stack1.pop();
                    stack2.pop();
                }
            }
            }
            return null;
        }
    }

9. 二叉树搜索树转换成排序双向链表

牛客网链接https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&&tqId=11179&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking解题思路:

前面已介绍过二叉搜索树的特点(因此已知当二叉搜索树中序遍历时是有序的)

①中序遍历这棵二叉树

②双向链表

代码如下:

public class Solution {
    //先写出一个中序遍历
    TreeNode prev=null;
    public void inOrder(TreeNode pCur){
        if(pCur==null)return ;
        inOrder(pCur.left);
        pCur.left=prev;
        if(prev!=null){
              prev.right=pCur;
        }
      prev=pCur;
          inOrder(pCur.right);
    }
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
            return null;
        }
        inOrder(pRootOfTree);
        TreeNode head=pRootOfTree;
        while(head.left!=null){
            head=head.left;
        }
        return head;
    }
}
10. 根据一棵树的前序遍历与中序遍历构造二叉树

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

解题思路:

①找到根结点

②通过中序遍历找到左右子树

③分别创建左右子树

代码如下:

class Solution {
//将preIndex设置为全局变量用来保证在递归的过程中当子树根结点返回到总根后的空指针异常
    public int preIndex=0;
    public TreeNode createTreeByPandI(int[]preorder,int[]inorder,int inbegin,int inend){
        if(inbegin>inend){
            //左树或者右树为空
            return null;
        }
        TreeNode root=new TreeNode(preorder[preIndex]);
        int rootIndex=findIndexOfI(inorder,inbegin,inend,preorder[preIndex]);
            if(rootIndex==-1){
                return null;
            }
            preIndex++;
            root.left=createTreeByPandI(preorder,inorder,inbegin,rootIndex-1);
            root.right=createTreeByPandI(preorder,inorder,rootIndex+1,inend);
            return root;
        }
    private int findIndexOfI(int[]inorder,int inbegin,int inend,int key){
        for(int i=inbegin;i<=inend;i++){

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

x++;

        root.left=createTreeByPandI(preorder,inorder,inbegin,rootIndex-1);
        root.right=createTreeByPandI(preorder,inorder,rootIndex+1,inend);
        return root;
    }
private int findIndexOfI(int[]inorder,int inbegin,int inend,int key){
    for(int i=inbegin;i<=inend;i++){

[外链图片转存中…(img-lZKwDbRW-1715730210401)]
[外链图片转存中…(img-RIxacV15-1715730210401)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C/C++ 是应用广泛的编程语言,其在数据结构应用方面也十分重要。面试中相关的 C/C++ 数据结构问题主要围绕数组、链表、二叉树和图等方面。以下是一些常见问题及其解答: 1. 如何反转一个单向链表? 答:可以使用三个指针来实现:cur 代表当前节点,pre 代表上一个节点,next 代表下一个节点。每次遍历时,将 cur 的 next 指向 pre,然后将三个指针分别向后移动即可。 2. 如何判断两个链表是否相交,并找出相交的点? 答:可以分别遍历两个链表,得到各自的长度。然后让长的链表先走 n 步,使得两个链表剩余的长度相等。接下来同时遍历两个链表,比较节点是否相同即可找出相交的点。 3. 如何判断一个二叉树是否为平衡二叉树? 答:可以计算每个节点的左右子树深度差,如果任何一个节点的深度差大于1,则此树不是平衡二叉树。可以使用递归实现,每次计算当前节点的深度,然后递归判断其左右子树是否平衡。 4. 如何实现图的深度优先搜索(DFS)和广度优先搜索(BFS)算法? 答:DFS 可以使用递归实现。从某个节点开始,逐个访问其未被访问的邻接节点,并将其标记为已访问。然后对每个未被访问的邻接节点递归调用 DFS 函数。BFS 可以使用队列实现。从某个节点开始,将其加入队列,并标记为已访问。然后从队列中弹出节点,并访问其所有未被访问的邻接节点,并将其加入队列中。重复此过程直到队列为空。 以上是一些常见的 C/C++ 数据结构面试问题及其解答。在面试中,除了掌握相关算法和数据结构知识外,还需多做练习和积累经验,才能更好地应对各种面试问题。 ### 回答2: C语言是一种用于编写系统级程序的高级编程语言,具有简单、高效、灵活等特点,是许多操作系统、编译器等软件的首选语言,也是许多企业在进行面试时重点考察的技能。在C/C++数据结构面试题中,经常会涉及到各种数据结构相关的算法和应用,测试面试者的算法思维能力和实现能力。 其中,常见的数据结构包括链表、栈和队列、二叉树、搜索树、哈希表等。在面试时,会常常涉及代码设计和实现,比如实现链表的插入、删除、查找操作,实现二叉树的遍历、查找操作等。 此外,在数据结构面试中,还经常涉及排序和查找算法,如冒泡排序、快速排序、归并排序、二分查找、哈希查找等。同时,面试者还需要解决一些较为复杂的算法问题,如图的最短路径问题,最小生成树问题等。 总之,C/C++数据结构面试题涵盖了运用数据结构的各种算法和实现方法,需要面试者具备扎实的编程基础和算法思维能力。在备战面试时,可以多做练习,熟悉常用的数据结构和算法,提高理解和实现能力,从而更好地应对面试挑战。 ### 回答3: 面试过程中常见的C/C++数据结构面试题有很多。以下就介绍几个常见的题目并给出解答。 1. 求两个有序数组的中位数 题目描述:给定两个升序排列的整形数组,长度分别为m和n。实现一个函数,找出它们合并后的中位数。时间复杂度为log(m+n)。 解答:这个问题可以使用二分法求解。首先,我们可以在两个数组中分别选出所谓的中间位置,即(i+j)/2和(k+l+1)/2,其中i和j分别是数组A的起始和结束位置,k和l分别是数组B的起始和结束位置。判断A[i+(j-i)/2]和B[k+(l-k)/2]的大小,如果A的中间元素小于B的中间元素,则中位数必定出现在A的右半部分以及B的左半部分;反之,则必定出现在A的左半部分以及B的右半部分。以此类推,每一次都可以删去A或B的一半,从而达到对数级别的时间复杂度。 2. 堆排序 题目描述:对一个长度为n的数组进行排序,时间复杂度为O(nlogn)。 解答:堆排序是一种常用的排序算法,在面试中也经常被考察。堆排序的具体过程是首先将数组构建成一个最大堆或最小堆,然后不断将堆顶元素与最后一个元素交换,并将最后一个元素从堆中剔除。这样,每次剔除后,堆都会重新调整,使得剩下的元素仍然保持堆的性质,直到堆中只剩下一个元素为止。 3. 链表反转 题目描述:反转一个单向链表,例如给定一个链表: 1->2->3->4->5, 反转后的链表为: 5->4->3->2->1。 解答:链表反转题目也是非常常见,其思路也比较简单。遍历链表,将当前节点的next指针指向前一个节点,同时记录当前节点和前一个节点,直至遍历到链表末尾。 以上这三个问题分别从二分法、堆排序和链表三个方面介绍了常见的C/C++数据结构面试题,希望能帮助面试者更好地准备面试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值