二叉树基础题(二)
来源:互联网 发布:尔雅网络课程账号密码 编辑:程序博客网 时间:2024/05/31 18:46
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/62424798冷血之心的博客)
二叉树基础题(一)
二叉树是在面试中经常被问到的,这里总结下二叉树的常用操作。
包括:
- 求二叉树中的节点个数: getNodeNumRec(递归),getNodeNum(迭代)
- 求二叉树的深度: getDepthRec(递归),getDepth(迭代)
- 分层遍历二叉树(按层次从上往下,从左往右): levelTraversal
- 求二叉树第K层的节点个数:getNodeNumKthLevelRec, getNodeNumKthLevel
- 求二叉树中叶子节点的个数:getNodeNumLeafRec, getNodeNumLeaf
- 判断两颗二叉树是否是相同的树:isSameRec, isSame
4、求二叉树中节点个数
/*********************************************************************** 4. 求二叉树中的节点个数: getNodeNumRec(递归),getNodeNum(迭代)**********************************************************************/ /** * 求二叉树中的节点个数递归解法: O(n) * (1)如果二叉树为空,节点个数为0 * (2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + * 右子树节点个数 + 1 */ public static int getNodeNumRec(TreeNode root){if(root==null)return 0;else return getNodeNumRec(root.left)+getNodeNumRec(root.right)+1;}/** * 求二叉树中的节点个数迭代解法O(n):基本思想同LevelOrderTraversal, * 即用一个Queue,在Java里面可以用LinkedList来模拟 */ public static int getNodeNum(TreeNode root){if(root==null)return 0;Queue<TreeNode> queue = new LinkedList<TreeNode>();queue.add(root);int count=1;while(!queue.isEmpty()){TreeNode cur = queue.remove();if(cur.left!=null){queue.add(cur.left);count++;}if(cur.right!=null){queue.add(cur.right);count++;}}return count;}
5、求二叉树的深度:
/*********************************************************************** 5. 求二叉树的深度: getDepthRec(递归),getDepth**********************************************************************//** * 求二叉树的深度(高度) 递归解法: O(n) * (1)如果二叉树为空,二叉树的深度为0 * (2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1 */ public static int getDepthRec(TreeNode root){if(root==null)return 0;int leftNode = getDepthRec(root.left);int rightNode = getDepthRec(root.right);return (leftNode>rightNode? leftNode:rightNode)+1;}public static int getDepth(TreeNode root){if(root==null)return 0;int depth=0;int curLevelNodeNums=1;int nextLevelNodeNums=0;LinkedList<TreeNode> queue = new LinkedList<TreeNode>();queue.add(root);while(!queue.isEmpty()){TreeNode cur = queue.remove();curLevelNodeNums--;if(cur.left!=null){queue.add(cur.left);nextLevelNodeNums++;}if(cur.right!=null){queue.add(cur.right);nextLevelNodeNums++;}if(curLevelNodeNums==0){depth++;curLevelNodeNums=nextLevelNodeNums;nextLevelNodeNums=0;}}return depth;}
6、分层遍历二叉树:
/*********************************************************************** 6.分层遍历二叉树(按层次从上往下,从左往右): levelTraversal **********************************************************************/ /** * 分层遍历二叉树(按层次从上往下,从左往右)迭代 * 相当于广度优先搜索,使用队列实现。队列初始化,将根节点压入队列。当队列不为空,进行如下操作:弹出一个节点 * ,访问,若左子节点或右子节点不为空,将其压入队列 */ public static void levelTraversal(TreeNode root){ if(root==null) return ; LinkedList<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); while(!queue.isEmpty()){ TreeNode cur = queue.remove(); System.out.print(cur.val+" "); if(cur.left!=null) queue.add(cur.left); if(cur.right!=null) queue.add(cur.right); } }
7、求二叉树中第K层的节点个数
/*********************************************************************** 7. 求二叉树第K层的节点个数:getNodeNumKthLevelRec(递归) getNodeNumKthLevel(迭代)**********************************************************************/ /** * 求二叉树第K层的节点个数 递归解法: * (1)如果二叉树为空或者k<1返回0 * (2)如果二叉树不为空并且k==1,返回1 * (3)如果二叉树不为空且k>1,返回root左子树中k-1层的节点个数与root右子树k-1层节点个数之和 * * 求以root为根的k层节点数目 等价于 求以root左孩子为根的k-1层(因为少了root那一层)节点数目 加上 * 以root右孩子为根的k-1层(因为少了root那一层)节点数目 * * 所以遇到树,先把它拆成左子树和右子树,把问题降解 * */ public static int getNodeNumKthLevelRec(TreeNode root, int k){ if(root==null || k<1) return 0; if(k==1) return 1; int leftNum = getNodeNumKthLevelRec(root.left, k-1); int rightNum = getNodeNumKthLevelRec(root.right, k-1); return leftNum+rightNum; } /** * 求二叉树第K层的节点个数 迭代解法: * 同getDepth的迭代解法 */ public static int getNodeNumKthLevel(TreeNode root, int k){ if(root==null) return 0; LinkedList<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); // 先将root存入队列 int i = 1; // 用来记录当前层数,和k做比较 int currentLevelNode = 1; int nextLevelNode = 0; // 当队列不为空,且当前层数小于k时,执行以下循环 while(!queue.isEmpty() && i<k){ // 当输入k大于深度时,返回0; TreeNode cur = queue.remove(); currentLevelNode--; if(cur.left!=null){ // 处理左子树 queue.add(cur.left); nextLevelNode++; } if(cur.right!=null){ // 处理右子树 queue.add(cur.right); nextLevelNode++; } if(currentLevelNode==0){ // 当前层的节点全部遍历完,则开始处理下一层。 currentLevelNode = nextLevelNode; nextLevelNode = 0; i++; } } // 当循环结束时,说明到达了K层 return currentLevelNode; }
8、求二叉树中叶子节点的个数:
/*********************************************************************** 8. 求二叉树中叶子节点的个数: getNodeNumLeafRec(递归),getNodeNumLeaf(迭代)**********************************************************************/ /** * 求二叉树中叶子节点的个数(递归) */ public static int getNodeNumLeafRec(TreeNode root){ if (root == null) return 0; if(root.left==null && root.right==null) return 1; return getNodeNumLeafRec(root.left)+getNodeNumLeafRec(root.right); } /** * 求二叉树中叶子节点的个数(迭代) * 还是基于Level order traversal */ public static int getNodeNumLeaf(TreeNode root){ if(root==null) return 0; LinkedList<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); int numLeaf = 0; while(!queue.isEmpty()){ TreeNode cur = queue.remove(); if(cur.left==null&&cur.right==null) // 判断是否是叶子节点 numLeaf++; if(cur.left!=null) // 有左孩子,则加入queue queue.add(cur.left); if(cur.right!=null) // 有右孩子,则加入queue queue.add(cur.right); } // 当循环退出时,返回numLeaf return numLeaf; }
9、判断两颗二叉树是否是相同的:
/*********************************************************************** 9. 判断两棵二叉树是否相同的树:isSameRec(递归), isSame(迭代)**********************************************************************/ /** * 判断两棵二叉树是否相同的树。 * 递归解法: * (1)如果两棵二叉树都为空,返回真 * (2)如果两棵二叉树一棵为空,另一棵不为空,返回假 * (3)如果两棵二叉树都不为空,如果对应的左子树和右子树都同构返回真,其他返回假 */ public static Boolean isSameRec(TreeNode root1,TreeNode root2){ if(root1==null&&root2==null) return true; if(root1!=null&&root2==null) return false; if(root1==null&&root2!=null) return false; if(root1.val==root2.val){ if(isSameRec(root1.left, root2.left)&&isSameRec(root1.right, root2.right)) return true; else return false; }else {return false;} } /** * 判断两棵二叉树是否相同的树(迭代) * 遍历一遍即可,这里用preorder */ public static Boolean isSame(TreeNode root1,TreeNode root2){ if(root1==null&&root2==null) return true; if(root1!=null&&root2==null) return false; if(root1==null&&root2!=null) return false; Stack<TreeNode> stack1 = new Stack<TreeNode>(); Stack<TreeNode> stack2 = new Stack<TreeNode>(); stack1.add(root1); stack2.add(root2); while(!stack1.isEmpty()&&!stack2.isEmpty()){ TreeNode cur1 = stack1.pop(); TreeNode cur2 = stack2.pop(); if(cur1.val!=cur2.val){ return false; }else{ if(cur1.right!=null) stack1.push(cur1.right); if(cur1.left!=null) stack1.push(cur1.left); if(cur2.right!=null) stack2.push(cur2.right); if(cur2.left!=null) stack2.push(cur2.left); } } return true; }
今天(2017-04-09)才发现上边判断二叉树是否是相同的非递归解法是错误的,
比如输入是
[10,5,15]和[10,5,null,null,15]
依然输出true,显然结果是错误的。
正解如下:
public static Boolean isSame(TreeNode root1,TreeNode root2){ // 如果两个树都是空树,则返回true if(root1==null && root2==null){ return true; } // 如果有一棵树是空树,另一颗不是,则返回false if(root1==null || root2==null){ return false; } Stack<TreeNode> s1 = new Stack<TreeNode>(); Stack<TreeNode> s2 = new Stack<TreeNode>(); s1.push(root1); s2.push(root2); while(!s1.isEmpty() && !s2.isEmpty()){ TreeNode n1 = s1.pop(); TreeNode n2 = s2.pop(); if(n1==null && n2==null){ continue; }else if(n1!=null && n2!=null && n1.val==n2.val){ s1.push(n1.right); s1.push(n1.left); s2.push(n2.right); s2.push(n2.left); }else{ return false; } } return true; }
测试类:
package com.ywq.package1;import BinaryTree.TreeNode;public class Main {/* 1 / \ 2 3 / \ / \ 4 5 7 6 */ public static void main(String[] args){TreeNode root = new TreeNode(1); TreeNode r2 = new TreeNode(2); TreeNode r3 = new TreeNode(3); TreeNode r4 = new TreeNode(4); TreeNode r5 = new TreeNode(5); TreeNode r6 = new TreeNode(6); TreeNode r7 = new TreeNode(7); root.left = r2; root.right = r3; r2.left = r4; r2.right = r5; r3.right = r6; r3.left = r7; TreeNode root1 = new TreeNode(1); TreeNode r21 = new TreeNode(2); TreeNode r31 = new TreeNode(3); TreeNode r41 = new TreeNode(4); TreeNode r51 = new TreeNode(5); TreeNode r61 = new TreeNode(6); TreeNode r71 = new TreeNode(7); root1.left = r21; root1.right = r31; r21.left = r41; r21.right = r51; r31.right = r61; r31.left = r71; System.out.println(getNodeNumRec(root)); System.out.println(getNodeNum(root)); System.out.println(getDepthRec(root)); System.out.println(getDepth(root)); levelTraversal(root); System.out.println(getNodeNumKthLevelRec(root.left,1)); System.out.println(getNodeNumKthLevel(root,2)); System.out.println(getNodeNumLeafRec(root)); System.out.println(getNodeNumLeaf(root)); System.out.println(isSameRec(root1, root)); System.out.println(isSame(root1, root)); }}// 建立二叉树节点类class TreeNode{int val;TreeNode left;TreeNode right;public TreeNode(int val){this.val = val;}}
如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,可以进群366533258一起交流学习哦~
13 2
- 二叉树基础题(二)
- 数据结构之二叉树基础二
- 二叉树(二)
- 二叉树(二)
- 二叉树(二)
- 二叉树(二)
- (二)二叉树
- 二叉树基础题(一)
- 二叉树基础题(三)
- LeetCode二叉树基础题(不断更新)
- 二叉查找树(二)
- 二叉树重建(二)
- 二叉树学习(二)
- 二叉树整理(二)
- 二叉树设计(二)
- 线索二叉树(二)
- 算法(二)二叉树
- PHP二叉树(二):平衡二叉树(AVL)
- 1067. 试密码(20)
- js 获取pc屏幕各种宽高的方法
- Map.Entry的用法实战
- jira出现加载插件失败情况JIRA Startup Failed
- JVM垃圾回收器总结
- 二叉树基础题(二)
- 快速幂学习及模板
- 勾搭程序员的 11 个技巧
- 大型敏捷框架SAFe的Program层
- 研究spring源码有所得
- CNN在句子相似性建模的应用--模型介绍篇
- 实用的oracle数据库恢复
- UVa1637纸牌游戏(紫书327)
- TCP三次握手四次挥手