目录

1.判断两个二叉树是否相同:节点数值相同,结构都相同

2.判断其中一棵树是否为另一棵树的子树

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

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

5.二叉树的创建及遍历: 给定一个带空格的前序二叉树序列 ,求它的 输出中序、后序遍历序列

6.二叉树的层序遍历:给二叉树的根节点 root ,返回其节点值的 层序遍历

7.二叉树p,q节点的 最近 公共 祖先LCA

8.二叉搜索树与双向链表:输入一棵二叉搜索树,将该二叉搜索树转换成一个 排序的 双向链表

9.从前序与中序遍历序列构造二叉树:  preorder 和 inorder ,构造二叉树并返回其根节点。

10. 从中序与后序遍历序列构造二叉树: inorder 和 postorder,构造并返回二叉树

11. 根据二叉树创建字符串:二叉树的根节点root,采用前序遍历 的方式:


1.判断两个二叉树是否相同:节点数值相同,结构都相同

    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;}//两个数的val相同return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);}

2.判断其中一棵树是否为另一棵树的子树

    //另一棵树的子树:给定两个二叉树,判断其中一个数subroot是否是另一棵树root的子树//首先判断两棵树是否都存在是否都为空,若两棵树相同也属于子树//判断对应的左右子树是否是相同的// 时间复杂度:O(m*n)public boolean isSubTree(TreeNode root, TreeNode subroot) {//只要有一个数为空就不符合子树条件if (root == null || subroot == null) return false;if (isSameTree(root, subroot)) {return true;  //判断两棵树是否相同}if (isSubTree(root.left, subroot)) {return true; //判断subroot是否是左子树}if (isSubTree(root.right, subroot)) {return true; //判断subroot是否是右边子树}return false;}

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

    //给定一个二叉树,判断它是否是高度平衡的二叉树。-->/平衡二叉树的子树也是平衡二叉树//解析:1.root左树高度-右树高度《=1;//2.root的左树是平衡点,右树也是平衡点   public int height(TreeNode root) {if (root == null) return 0;int leftheight = height(root.left);int rightheight = height(root.right);if (leftheight >= 0 && rightheight >= 0 &&Math.abs(leftheight - rightheight) <= 1) {return Math.max(leftheight,rightheight) +1;}else {return -1;}}
//时间复杂度O(N)public boolean isBalanced(TreeNode root) {if (root == null) return true;return height(root) >= 0;}

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

//给你一个二叉树的根节点 root , 检查它是否轴对称--->
//解析:1.查看左树和右树是否对称:左树的左子树和右边树的右子树相同//2.public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {if (leftTree != null && rightTree ==null) return false;if (leftTree == null && rightTree !=null) return false;if (leftTree == null && rightTree ==null) return true;if (leftTree.val != rightTree.val) return false;return isSymmetricChild(leftTree.left,rightTree.right) &&isSymmetricChild(leftTree.right,rightTree.left);}public boolean isSymmetric(TreeNode root) {if (root == null) return true;return isSymmetricChild(root.left,root.right);}

5.二叉树的创建及遍历: 给定一个带空格的前序二叉树序列 ,求它的 输出中序、后序遍历序列

//  二叉树的创建及遍历 给定一个带空格的前序二叉树序列 ,求它的   输出中序、后序遍历序列      --->
//解析:1.前序遍历可以确定根节点,public static void inorder(TreeNode root) {if (root == null)  return;inorder(root.left);System.out.print(root.val+" ");inorder(root.right);}public static int i = 0;public static TreeNode createTree(String str) {TreeNode root = null;if (str.charAt(i) != '#') {root = new TreeNode(str.charAt(i)); //当前不是#即为根节点i++;root.left = createTree(str);root.right = createTree(str);}else {i++;  //遇到#只需i++}return root;}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while (scanner.hasNextLine()) {String str = scanner.nextLine();TreeNode root = createTree(str);inorder(root);}}

6.二叉树的层序遍历:给二叉树的根节点 root ,返回其节点值的 层序遍历

// (即逐层地,从左到右访问所有节点)。-----》用队列完成//解析:public void levelOder(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);}}}//============层序遍历=============================================================//
//    public List<List<Integer>> levelOrder(TreeNode root) {
//        List<List<Integer>> ret = new ArrayList<>();
//        if (root == null) return ret;
//
//        Queue<TreeNode> queue1 = new LinkedList<>();
//        queue1.offer(root); //根放入队列
//
//        while (!queue1.isEmpty()) {
//            int size = queue1.size(); // size代表当前层有多少个节点
//            List<Integer> list = new ArrayList<>();
//            while (size != 0) {
//                TreeNode cur = queue1.poll();
//                list.add(cur.val);
//                if (cur.left != null) {
//                    queue1.offer(cur.left);
//                }
//                if (cur.right != null) {
//                    queue1.offer(cur.right);
//                }
//                size--;
//            }
//            ret.add(list);
//        }
//        return ret;
//    }

7.二叉树p,q节点的 最近 公共 祖先LCA

  /*孩子双亲表示法:---》链表求交点(用栈保存路径)1.用两个栈的存储p,q路径(如何找到根节点到指定节点路径???--》遍历:)2.求栈的大小3.让栈中多的元素出差值个元素4.开始出栈,直到栈顶元素相同,即此时是LCA最近公共祖先** */
//获取路径root--》node://root根节点 node指定节点,stack存储指定节点路径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; //若根节点为node,找到了指定节点
//如果不是根节点,则需要在左右树寻找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();  //左右树都没找到指定节点node,则需要弹出pop()return false;}public TreeNode lowestCommonAncestor1(TreeNode root, TreeNode p, TreeNode q) {if(root == null) return null;Stack<TreeNode> stack1 = new Stack<>();getPath(root,p,stack1);//存储root到p的路径到stack1Stack<TreeNode> stack2 = new Stack<>();getPath(root,q,stack2);//存储root到q的路径到stack2int size1 = stack1.size();  //得到两个栈的大小int size2 = stack2.size();if (size1 > size2) {  //取两个栈差值个元素int size = size1-size2;while (size != 0) {stack1.pop();  //size大的栈stack1开始出元素,直至两个栈元素相同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大的栈stack2开始出元素,直至两个栈元素相同size--;}while (!stack1.isEmpty() && !stack2.isEmpty()) {if (stack1.peek() == stack2.peek()) {return stack1.pop();}else {stack1.pop();stack2.pop();}}}return null;}

8.二叉搜索树与双向链表:输入一棵二叉搜索树,将该二叉搜索树转换成一个 排序的 双向链表

* 解析:1.二叉搜素树:左树<根<右树--->  中序遍历  即有序
* 2.双向链表:left做前驱prev,right后继next
* 3.操作:中序遍历过程中:修改每个节点的left,right
*
* */TreeNode prev = null;public void inorder1(TreeNode pCur) {if (pCur == null) return;inorder1(pCur.left);  //左pCur.left = prev;if (prev != null) {prev.right = pCur;}prev = pCur;
//        System.out.print(pCur+" ");//根inorder1(pCur.right);  //右}public TreeNode convert(TreeNode pRootOfTree) {if (pRootOfTree == null) return null;inorder1(pRootOfTree);TreeNode head = pRootOfTree;while (head.left != null) {head = head.left;}return head;}

9.从前序与中序遍历序列构造二叉树:  preorder 和 inorder ,构造二叉树并返回其根节点。

/*105. 从前序与中序遍历序列构造二叉树: 两个整数数组 preorder 和 inorder ,构造二叉树并返回其根节点。preorder 是二叉树的先序遍历(可得根节点),inorder是其中序遍历(确定左右树元素),*解析:1.先将Pi下标元素,创建为root2.中序遍历数组中找到当前下标Pi元素3.root.left=?4.root.right=?
* *///通过前序中序遍历创建树:前序遍历数组preorder,索引下标preindex;  中序遍历数组inorder,下标(左inbegin  右inend)public int preIndex = 0;public TreeNode1 createNewTree(int[] preorder,int[] inorder,int inbegin,int inend) {//满足此条件 则 说明 没有左树或者右树if (inbegin > inend) return null;//此处TreeNode为char类型,但是应该是int类型,需要在前面定义class TreeNode { public int val;}TreeNode1 root = new TreeNode1(preorder[preIndex]);//寻找前序遍历preIndex下标出的元素(preorder[preIndex])  在中序遍历  里对应的位置int rootindex = findIndexOfInorder(inorder,inbegin,inend,preorder[preIndex]);if (rootindex == -1) return null;preIndex++;root.left = createNewTree(preorder,inorder,inbegin,rootindex-1); //左右树递归root.right = createNewTree(preorder,inorder,rootindex+1,inend);return root;}//寻找其对应在中序遍历的位置::中序遍历--起始索引值--数值keyprivate int findIndexOfInorder(int[] inorder,int inbegin,int inend,int key) {for (int i = inbegin; i <= inend; i++) {if (inorder[i] == key) {return i;}}return -1;}public TreeNode1 buildTree(int[] preorder,int[] inorder) {if (preorder == null || inorder == null) return null;return createNewTree(preorder,inorder,0,inorder.length-1);}

10. 从中序与后序遍历序列构造二叉树: inorder 和 postorder,构造并返回二叉树

    /* * 106. 从中序与后序遍历序列构造二叉树:给定两个整数数组 inorder 和 postorderinorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,构造并返回二叉树*解析:1.先将Pi下标元素,创建为root2.中序遍历数组中找到当前下标Pi元素3.root.right=?4.root.left=?*///通过前序中序遍历创建树:前序遍历数组preorder,索引下标preindex;  中序遍历数组inorder,下标(左inbegin  右inend)public int postIndex = 0;public TreeNode1 createNewTree1(int[]inorder, int[] postorder, int inbegin,int inend) {//满足此条件 则 说明 没有左树或者右树if (inbegin > inend) return null;//此处TreeNode为char类型,但是应该是int类型,需要在前面定义class TreeNode { public int val;}TreeNode1 root = new TreeNode1(postorder[postIndex]);//寻找前序遍历preIndex下标出的元素(preorder[preIndex])  在中序遍历  里对应的位置int rootindex = findIndexOfInorder1(inorder,inbegin,inend,postorder[postIndex]);if (rootindex == -1) return null;postIndex--;//分别创建右子树,和左子树//左右子树下标分别为:左边:inbegin,rootindex-1;  右边:rootindex+1,inendroot.right = createNewTree1(inorder,postorder,rootindex+1,inend); //左右树递归root.left = createNewTree1(inorder,postorder,inbegin,rootindex-1);return root;}//寻找其对应在中序遍历的位置::中序遍历--起始索引值--数值keyprivate int findIndexOfInorder1(int[] inorder,int inbegin,int inend,int key) {for (int i = inbegin; i <= inend; i++) {if (inorder[i] == key) {return i;}}return -1;}public TreeNode1 buildTree1(int[] inorder,int[] postorder) {if (postorder == null || inorder == null) return null;postIndex = postorder.length-1;return createNewTree1(inorder,postorder,0,inorder.length-1);}

11. 根据二叉树创建字符串:二叉树的根节点root,采用前序遍历 的方式:

 /*根据二叉树创建字符串:二叉树的根节点root,,采用前序遍历 的方式:将二叉树转化为: 一个由 括号和整数  组成的字符串,返回构造出的字符串。(空格以括号的形式输出)**/public void treeToString(TreeNode t,StringBuilder sb) {if (t == null) return;sb.append(t.val); //根不为空,进行拼接appendif (t.left != null) { //t的左边不为空,拼接左括号“(”sb.append("(");treeToString(t.left,sb); //继续递归操作,查找每一个左树sb.append(")");//左树走完,拼接append右括号“)”}else {  //左树为空的情况下,考虑左子树的右树if (t.right ==null) {return;}else {sb.append("()");}}//考虑右树的情况if(t.right ==null) return;sb.append("(");treeToString(t.right,sb);//执行右树递归操作sb.append(")");//右树树走完,拼接append右括号“)”}public String tree2str(TreeNode root) {if (root == null) return null;StringBuilder sb = new StringBuilder();  //StringBuilder用拼接操作,不会产生太多临时变量treeToString(root,sb);return sb.toString();}

【JAVA】数据结构——二叉树 例题练习及代码详解相关推荐

  1. java 搜索_Java实现搜索功能代码详解

    首先,我们要清楚搜索框中根据关键字进行条件搜索发送的是Get请求,并且是向当前页面发送Get请求 //示例代码 请求路径为当前页面路径 "/product" 当我们要实现多条件搜索 ...

  2. 数据结构-二叉树、搜索树、平衡二叉树详解及C语言实现

    目录 1. 树概念及结构 1.1.树的概念 1.2.树的定义 1.3.树的一些基本术语 1.4.树的表示 1.4.1.儿子兄弟表示法 1.4.2.双亲表示法 1.4.3.孩子表示法 2.二叉树及存储结 ...

  3. java sendmessage_SendMessage、PostMessage原理和源代码详解

    本文讲解SendMessage.PostMessage两个函数的实现原理,分为三个步骤进行讲解,分别适合初级.中级.高级程序员进行理解,三个步骤分别为: 1.SendMessage.PostMessa ...

  4. java语言链栈_Java语言实现数据结构栈代码详解

    近来复习数据结构,自己动手实现了栈.栈是一种限制插入和删除只能在一个位置上的表.最基本的操作是进栈和出栈,因此,又被叫作"先进后出"表. 首先了解下栈的概念: 栈是限定仅在表头进行 ...

  5. java编程数据溢出问题_Java数据溢出代码详解

    Java数据溢出代码详解 发布时间:2020-10-05 15:08:31 来源:脚本之家 阅读:103 作者:Pony小马 java是一门相对安全的语言,那么数据溢出时它是如何处理的呢? 看一段代码 ...

  6. java 文件下载详解_Java 从网上下载文件的几种方式实例代码详解

    废话不多说了,直接给大家贴代码了,具体代码如下所示: package com.github.pandafang.tool; import java.io.BufferedOutputStream; i ...

  7. java 委托机制_通过反射实现Java下的委托机制代码详解

    简述 一直对Java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块API public Class Delegater()//空参构造,该类管理委托实例并 ...

  8. java委托机制教程_通过反射实现Java下的委托机制代码详解

    简述 一直对java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块api public class delegater()//空参构造,该类管理委托实例并 ...

  9. java一个方法排他调用_Java编程实现排他锁代码详解

    一 .前言 某年某月某天,同事说需要一个文件排他锁功能,需求如下: (1)写操作是排他属性 (2)适用于同一进程的多线程/也适用于多进程的排他操作 (3)容错性:获得锁的进程若Crash,不影响到后续 ...

  10. java中math的方法_Java中Math类常用方法代码详解

    近期用到四舍五入想到以前整理了一点,就顺便重新整理好经常见到的一些四舍五入,后续遇到常用也会直接在这篇文章更新... public class Demo{ public static void mai ...

最新文章

  1. 最后2周 | 高级转录组分析和R语言数据可视化第十一期 (报名线上课还可免费参加线下课)...
  2. Careercup | Chapter 1
  3. setwindowpos怎么改变z序_置顶窗口SetWindowPos()的用法
  4. 最近心理很烦,谁能帮帮我?
  5. 中央财经大学计算机专业排名,中央财经大学怎么样 2021年全国排名多少
  6. sharepoint 2010 记录管理 对象模型
  7. 软工网络15个人阅读作业2——提问题
  8. Linux之CPU物理核与逻辑核
  9. niginx的高可用配置(HA)
  10. 9.28 csp-s模拟测试54 x+y+z
  11. C# 词法分析器(四)构造 NFA
  12. centos oracle libaio哪下载,linux 安装libaio
  13. 在线图片托管服务imgur
  14. 转贴:Spring vs. EJB
  15. 云计算要掌握哪些知识点 该怎么学云计算开发
  16. Windows10系统安装详细教程
  17. D3D9学习笔记之基础几何体的深入应用(一)
  18. web端的shader Threejs飞线
  19. 图片旋转90度解决办法
  20. win10系统分区方案教程

热门文章

  1. 永洪BI-报表生成URL
  2. c语言页面置换算法报告,C语言实现页面置换算法
  3. elcipse 本地安装 svn插件:subclipse
  4. Java单例模式的双if
  5. 病房管理系统c语言设计,病房呼叫系统设计与仿真
  6. HDOJ 1025 DP
  7. c语言共有34种运算符,C语言运算符与表达式
  8. ShellServiceObjectDelayLoad注册表键值作用
  9. 投资 - 课程学习: 实现财富自由的科学路径-量化投资
  10. 苹果计算机磁盘格式,苹果电脑上怎么进行格式化磁盘?