二叉树练习

  • 一、选择题
    • 1. 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为( )
    • 2.在具有 2n 个结点的完全二叉树中,叶子结点个数为( )
    • 3.一棵完全二叉树的节点数位为531个,那么这棵树的高度为( )
    • 4.一个具有767个节点的完全二叉树,其叶子节点个数为()
    • 5. 某完全二叉树按层次输出(同一层从左到右)的序列为 ABCDEFGH 。该完全二叉树的前序序列为()
    • 6. 二叉树的先序遍历和中序遍历如下:先序遍历:EFHIGJK;中序遍历:HFIEJKG.则二叉树根结点为()
    • 7. 设一课二叉树的中序遍历序列:badce,后序遍历序列:bdeca,则二叉树前序遍历序列为()
    • 8. 某二叉树的后序遍历序列与中序遍历序列相同,均为 ABCDEF ,则按层次输出(同一层从左到右)的序列为()
  • 二、OJ题目
    • 1. 检查两颗树是否相同
    • 2. 另一颗树的子树
    • 3. 判断一颗二叉树是否是平衡二叉树
    • 4. 对称二叉树
    • 5. 二叉树的构建及遍历
    • 6. 二叉树的分层遍历
    • 7. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先
    • 8. 根据一棵树的前序遍历与中序遍历构造二叉树
    • 9. 根据一棵树的中序遍历与后序遍历构造二叉树
    • 10. 二叉树创建字符串
    • 11. 二叉树前序非递归遍历实现
    • 12. 二叉树中序非递归遍历实现
    • 13. 二叉树后序非递归遍历实现

一、选择题

1. 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为( )

A 不存在这样的二叉树
B 200
C 198
D 199
正确答案B
解析:叶子结点的个数等于度为2的结点数+1.

2.在具有 2n 个结点的完全二叉树中,叶子结点个数为( )

A n
B n+1
C n-1
D n/2
正确答案A
解析:假设叶子结点的个数为x,那么度为2的结点的个数为x-1,叶子结点和度为2的结点的和为2n-1,因此:
x+x-1=2n-1
x=n

3.一棵完全二叉树的节点数位为531个,那么这棵树的高度为( )

A 11
B 10
C 8
D 12
正确答案B
解析:利用公式高度= l o g 2 ( 531 + 1 ) log_2(531+1) log2​(531+1),向上取整,结果为10。

4.一个具有767个节点的完全二叉树,其叶子节点个数为()

A 383
B 384
C 385
D 386
正确答案B
解析:假设叶子结点个数为x个,度为2的结点个数为x-1个,x+x-1=767,解得x=384.

5. 某完全二叉树按层次输出(同一层从左到右)的序列为 ABCDEFGH 。该完全二叉树的前序序列为()

A: ABDHECFG
B: ABCDEFGH
C: HDBEAFCG
D: HDEBFGCA
正确答案A

6. 二叉树的先序遍历和中序遍历如下:先序遍历:EFHIGJK;中序遍历:HFIEJKG.则二叉树根结点为()

A: E
B: F
C: G
D: H
正确答案A

7. 设一课二叉树的中序遍历序列:badce,后序遍历序列:bdeca,则二叉树前序遍历序列为()

A: adbce
B: decab
C: debac
D: abcde
正确答案D
解析

8. 某二叉树的后序遍历序列与中序遍历序列相同,均为 ABCDEF ,则按层次输出(同一层从左到右)的序列为()

A: FEDCBA
B: CBAFED
C: DEFCBA
D: ABCDEF
正确答案A
解析

二、OJ题目

1. 检查两颗树是否相同

相同的树

class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {//总共有四种情况,两棵都空,其中一棵为空,两棵都非空if(p==null&&q==null){//两棵树都为空return true;}if(p==null&&q!=null){return false;}else if(p!=null&&q==null){return false;}else{return p.val==q.val&&isSameTree(p.left,q.left)&& isSameTree(p.right,q.right);}}
}

2. 另一颗树的子树

另一棵树的子树
利用上面写的相同的树的函数

class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {//总共有四种情况,两棵都空,其中一棵为空,两棵都非空if(p==null&&q==null){//两棵树都为空return true;}if(p==null&&q!=null){return false;}else if(p!=null&&q==null){return false;}else{return p.val==q.val&&isSameTree(p.left,q.left)&& isSameTree(p.right,q.right);}}public boolean isSubtree(TreeNode root, TreeNode subRoot) {if(root==null&&subRoot==null){return true;}if(root!=null&&subRoot==null){//空树一定是另一棵树的子树return true;}if(root==null&& subRoot!=null){return false;}//两棵树均存在//检测是否为同一棵树if(isSameTree(root,subRoot)){return true;}//不是同一棵树,看左子树是不是,再看右子树return isSubtree(root.left,subRoot)||isSubtree(root.right,subRoot);}
}

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

平衡二叉树

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;}public boolean isBalanced(TreeNode root) {if(root==null){return true;}int LeftHeight=height(root.left);int RightHeight=height(root.right);if(Math.abs(LeftHeight-RightHeight)>1){return false;}return isBalanced(root.left)&&isBalanced(root.right);}
}

4. 对称二叉树

对称二叉树

class Solution {public boolean isSymmetric(TreeNode ll,TreeNode rr){if(ll==null&&rr==null){return true;}//两棵树中有一棵空if(ll==null||rr==null){return false;}return ll.val==rr.val&& isSymmetric(ll.left,rr.right)&&isSymmetric(ll.right,rr.left);}public boolean isSymmetric(TreeNode root) {if(root==null){return true;}return isSymmetric(root.left,root.right);}
}

5. 二叉树的构建及遍历

二叉树遍历

//IO类型的OJ题目
//1.需要创建Main类
//2.需要提供一个main方法
//3.需要循环接收每个测试用例
//4.需要用户自己导入所需要用到的包
import java.util.Scanner;
public class Main{//对二叉树的结点进行定义public static class TreeNode{char value;TreeNode left;TreeNode right;public TreeNode(char value){this.value=value;}}//指向二叉树的根结点TreeNode root;int index=0;void createBinaryTree(String prestr,char invalid){index=0;root=createBinaryTreeN(prestr,invalid);}TreeNode createBinaryTreeN(String prestr,char invalid){TreeNode treeRoot = null;if(index<prestr.length() && prestr.charAt(index)!=invalid){//1.创建根结点treeRoot=new TreeNode(prestr.charAt(index));//2.创建根结点的左子树++index;treeRoot.left=createBinaryTreeN(prestr,invalid);//3.创建根结点的右子树++index;treeRoot.right=createBinaryTreeN(prestr,invalid);}return treeRoot;
}public void InOrder(){InOrder(root);System.out.println();}private void InOrder(TreeNode treeRoot){if(treeRoot!=null){InOrder(treeRoot.left);System.out.print(treeRoot.value+" ");InOrder(treeRoot.right);}}public static void main(String[] args){Scanner sc=new Scanner(System.in);while(sc.hasNext()){//接收前序遍历的结果String str=sc.nextLine();Main tree=new Main();tree.createBinaryTree(str,'#');tree.InOrder();}}}

6. 二叉树的分层遍历

二叉树的层序遍历

class Solution {public List<List<Integer>> levelOrder(TreeNode root) {//1.申请ArrayList的对象用来保存该层的结点//2.以循环的方式将该层的结点整体遍历完,----下一层的所有结点已经全部入队列//3.将ArrayList中保存的该层遍历结果保存起来List<List<Integer>> list=new ArrayList<>();if(root==null){return list;}//借助队列对二叉树完成分层遍历Queue<TreeNode> q=new LinkedList<>();q.offer(root);while(!q.isEmpty()){//队列中保存的就是同一层的结点//一次性将该层的结点遍历完int levelsize=q.size();List<Integer> levelval=new ArrayList<>(); for(int i=0;i<levelsize;i++){TreeNode cur=q.poll();levelval.add(cur.val);if(cur.left!=null){q.offer(cur.left);}if(cur.right!=null){q.offer(cur.right);}}list.add(levelval);}return list;}
}

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

找公共祖先OJ链接
面试中要和面试官讨论:

  1. 如果树是采用双亲表示法或者孩子双亲表示法
    求最近公共祖先问题:转化为两个链表相交求交点
  2. 二叉搜索树结构:
    最左侧结点最小,最右侧结点最大。

借鉴第一种方式解题:

class Solution {//获取从根到某个结点对应路径中包含的所有结点boolean getNodePath(TreeNode root,Stack<TreeNode>spath,TreeNode node){if(root==null||node==null){return false;}spath.push(root);if(root==node){return true;}if(getNodePath(root.left,spath,node)){return true;}if(getNodePath(root.right,spath,node)){return true;}spath.pop();return false;}public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root==null||p==null||q==null){return null;}//找从root到p或q对应路径中包含的所有结点Stack<TreeNode> ppath=new Stack<>();Stack<TreeNode> qpath=new Stack<>();getNodePath(root,ppath,p);getNodePath(root,qpath,q);int psize=ppath.size();int qsize=qpath.size();while(!ppath.empty()&&!qpath.empty()){if(ppath.peek()==qpath.peek()){return ppath.peek();}if(psize>qsize){ppath.pop();psize--;}else if(psize<qsize){qpath.pop();qsize--;}else{ppath.pop();qpath.pop();psize--;qsize--;}}return null;}
}

8. 根据一棵树的前序遍历与中序遍历构造二叉树

解题思路

  1. 从前序遍历结果中找二叉树的根结点
  2. 在中序遍历结果中找根结点的位置pos,在pos左侧的元素就是根的左子树,在pos右侧的元素就是根的右子树,以pos为分界点:将中序遍历结果划分成两个区间。
  3. 还原根结点,递归还原根的左子树------根据中序划分的左子树区间,递归还原根的右子树----根据中序划分根的右子树区间。
class Solution {int index=0;//最后要返回根结点TreeNode reBuilderTree(int[] preorder,int[] inorder,int left,int right){//给递归设置一个出口if(index>=preorder.length||left>=right){return null;}//1.从前序遍历结果中确定根 index的位置就是根的位置//preorder[index]--就是根//2.从中序遍历结果中找根的位置posint pos=left;while(pos<right){if(inorder[pos]==preorder[index]){break;}pos++;}//还原根结点TreeNode root=new TreeNode(preorder[index]);index++;//递归还原根的左子树root.left=reBuilderTree(preorder,inorder,left,pos);//递归还原根的右子树root.right=reBuilderTree(preorder,inorder,pos+1,right);return root;}public TreeNode buildTree(int[] preorder, int[] inorder) {index=0;return reBuilderTree(preorder,inorder,0,inorder.length);}
}

9. 根据一棵树的中序遍历与后序遍历构造二叉树

class Solution {int index=0;TreeNode rebuildTree(int[] postorder,int[] inorder,int left,int right){if(index<0 || left>=right){return null;}//1.首先在后序结果中确定根结点//postorder[index]就是根//2.在中序序列中找根的位置pos,确定根的左右子树int pos=left;//从左边界开始找while(pos < right){if(postorder[index] == inorder[pos]){break;}pos++;}//还原根结点TreeNode root=new TreeNode(postorder[index]);index--;//递归还原根的右子树root.right=rebuildTree(postorder,inorder,pos+1,right);//递归还原根的左子树root.left=rebuildTree(postorder,inorder,left,pos);return root;}public TreeNode buildTree(int[] inorder, int[] postorder) {index=postorder.length-1;return rebuildTree(postorder,inorder,0,inorder.length);}
}

10. 二叉树创建字符串

二叉树创建字符串
你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。

空节点则用一对空括号 “()” 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

class Solution {//要使用递归,所以重新封装一个方法void tree2str(TreeNode root, StringBuilder sb){if(root==null){return;}//先转化根结点sb.append(root.val);//递归转化根结点的左子树if(root.left==null){if(root.right==null){return;}else{sb.append("()");}}else{sb.append('(');tree2str(root.left,sb);sb.append(')');}//递归转化根结点的右子树if(root.right==null){return;}else{sb.append('(');tree2str(root.right,sb);sb.append(')');}}public String tree2str(TreeNode root) {StringBuilder sb=new StringBuilder();tree2str(root,sb);return sb.toString();}
}

11. 二叉树前序非递归遍历实现

class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> list=new ArrayList<>();if(root==null){return list;}Stack<TreeNode> s=new Stack<>();TreeNode cur=root;while(!s.empty()||cur!=null){//从上往下 遍历最左侧路径中的每个结点,并将其右子树保存起来  while(cur!=null){list.add(cur.val);if(cur.right!=null){s.push(cur.right);}cur=cur.left;}if(!s.empty()){cur=s.pop();}}return list;}
}

12. 二叉树中序非递归遍历实现

class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> list=new ArrayList<>();if(root==null){return list;}TreeNode cur=root;Stack <TreeNode> s=new Stack<>();while(cur!=null||!s.empty()){//1.找当前二叉树最左侧的结点,并将路径中遇到的所有结点都保存起来while(cur!=null){s.push(cur);cur=cur.left;}cur=s.pop();list.add(cur.val);cur=cur.right;}return list;}
}

13. 二叉树后序非递归遍历实现

class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> list=new ArrayList<>();if(root==null){return list;}Stack <TreeNode> s=new Stack<>();TreeNode cur=root;TreeNode prev = null ; //用来标记刚刚遍历过的结点//先找到最左侧结点while(!s.empty()||cur!=null){while(cur!=null){s.push(cur);cur=cur.left;}TreeNode top=s.peek();if(top.right==null||top.right==prev){list.add(top.val);//右子树不存在就可以直接遍历根结点,或者右子树已经遍历了prev=top;s.pop(); }else{cur=top.right;}}return list;}
}

二叉树练习题及答案解析相关推荐

  1. pmp练习题及答案解析

    4.08pmp练习题及答案解析 DCCAA 1.客户提出的一项变更需求已经实现,并得到了客户的认可.但项目经理发现为了满足客户的这个需求,团队不得不加班才没有影响项目的进度基准.项目经理把这个经历整理 ...

  2. c语言二级填空题及答案,2012年计算机等级二级C语言填空题练习题及答案解析(2)...

    求和.平均值 1. 请补全main函数,该函数的功能是:从键盘输入一个长整数,如果这个数是负数,则取它的的绝对值,并显示出来. main() {long int n; clrscr() ; print ...

  3. 2011年6月安徽省计算机水平(二级c语言试题)及解析答案,2011年计算机等级二级C语言填空题练习题及答案解析(2)...

    求和.平均值 1. 请补全main函数,该函数的功能是:从键盘输入一个长整数,如果这个数是负数,则取它的的绝对值,并显示出来. main() {long int n; clrscr() ; print ...

  4. 一九四六年首台电子计算机,2012年计算机一级MsOffice第四十九套练习题及答案解析...

    1). 下列关于世界上第一台电子计算机ENIAC的叙述中,错误的是 A) 它是1946年在美国诞生的 B) 它主要采用电子管和继电器 C) 它是首次采用存储程序控制使计算机自动工作 D) 它主要用于弹 ...

  5. 计算机用户要以ADSL,2012年计算机一级MsOffice第三十三套练习题及答案解析

    1). 冯•诺依曼(Von Neumann)在总结ENIAC的研制过程和制订EDVAC计算机方案时,提出两点改进意见,它们是 A) 采用ASCII编码集和指令系统 B) 引入CPU和内存储器的概念 C ...

  6. 单位内部一个计算机系统属于,2012年计算机一级MsOffice第五十九套练习题及答案解析...

    1). 微型计算机的硬件系统中最核心的部件是 A) 内存储器 B) 输入输出设备 C) CPU D) 硬盘 2). Internet实现了分布在世界各地的各类网络的互联,其最基础和核心的协议是 A) ...

  7. C# 数组练习题及答案解析

    1.根据班级人数创建一个数组,要求每个人的姓名都要放进去 Console.Write("请输入班级人数:"); int n = int.Parse(Console.ReadLine ...

  8. oracle子查询练习题与答案解析 笔记 小白练习!(内有福利)

    ​​​​​​​ -- from(emp) -->sum-->select -- 创建表 -- 学生表 student -- sno 学号.编号 -- sname 学生姓名 -- sage ...

  9. 标准配置输入设备微型计算机,2012年计算机一级MsOffice第五十三套练习题及答案解析...

    1). 操作系统管理用户数据的单位是 A) 扇区 B) 文件 C) 磁道 D) 文件夹 2). 1KB的存储容量能存储的汉字内码的个数是 A) 128 B) 256 C) 512 D) 1024 3) ...

最新文章

  1. 关于ExtJS在使用下拉列表框的二级联动获取数据
  2. Oracle中SQL解析的流程
  3. 【weblogic】部署jfinal编写的应用
  4. pyqt 子窗口控制主窗口绘图_实战PyQt5: 005-主窗口QMainWindow
  5. 8屏 旌宇多屏管理软件_如何选择拼接屏,不能说的秘密,都在这!
  6. JAVA多线程程序ProgressBar
  7. Solr部署到tomcat
  8. python适配器模式角色_适配器模式(Adapter模式)详解
  9. 剑指offer——面试题23:从上往下打印二叉树
  10. 帆软 在线Cron表达式
  11. linux用sed命令修改IP地址,通过sed命令获取IP地址
  12. 哲学家进餐问题pv_用C语言实现哲学家进餐的问题
  13. Photoshop-置换贴图-原理
  14. 云端卫士实战录 React + Redux 前端项目实践
  15. 智能优化算法:海鸥算法原理及Matlab代码
  16. 周小川深度解读:DC/EP和数字人民币e-CNY
  17. 2019 ICPC南昌网络赛 E题 Magic Master 【双向队列】
  18. 本章设计了三种不同的神经网络,神经网络简答题
  19. html3d粒子球,Canvas粒子系统:3D球体
  20. juniper:SRX-产品简介

热门文章

  1. 2021-06-29《旋转基元重建增强和鲁棒6D姿态估计》
  2. 发生系统错误 1275.此驱动程序被阻止加载 解决方案
  3. Copyleaks:AI抄袭和内容检测工具
  4. 2019.7.14 并查集P1197 [JSOI2008]星球大战 说能过那是假的(动态规划) cometoj #c6 双倍快乐
  5. 解决chrome版本过低
  6. 逍遥模拟器过检测_BMS选用什么样的电池模拟器
  7. python微信好友检测_用Python调教微信,实现自动回复 和 微信好友分布,好友性别图,好友标签...
  8. 文献阅读_基于多模态数据语义融合的旅游在线评论有用性识别研究
  9. python中int什么意思_python 的 int() 函数是什么,怎么用
  10. 钢筋混凝土和预应力钢筋混凝土的区别