二叉树相关面试题目之实例总结
来源:互联网 发布:八卦九宫打法优化版 编辑:程序博客网 时间:2024/06/07 05:28
编码解决二叉树问题能够帮助我们深入理解递归思想,并能提高代码能力。在这里总结上一周实现的五个小例题,从《程序员代码面试指南》里面挑选出来的。它们是:二叉树的序列化和反序列化、找到二叉树中指定值的最长路径长度、找到二叉树中最大的二叉搜索子树、层序打印、搜索二叉树中两个错误的节点和判断二叉树r1是否包含二叉树r2的全部拓扑结构。
1、二叉树的序列化和反序列化
代码包含二叉树的先序序列化、先序反序列化,以及层序的序列化、层序的反序列化。下面是代码部分:
//先序序列化这棵树public static String serialByPre(Node root) {//递归实现二叉树的先序序列化 if (root == null) { return "#!"; } String res = root.data + "!"; res += serialByPre(root.left); res += serialByPre(root.right); return res;}public static Node reconByPreString(String str) {//字符串反序列化二叉树 String[] vals = str.split("!"); Queue<String> queue = new LinkedList<String>(); for (int i = 0; i < vals.length; i++) { queue.offer(vals[i]); } return reconPreOrder(queue);}private static Node reconPreOrder(Queue<String> queue) {//对字符串队列,使用递归方法将其反序列化为二叉树 String value = queue.poll(); if (value.equals("#")) { return null; } Node head = new Node(Integer.parseInt(value)); head.left = reconPreOrder(queue); head.right = reconPreOrder(queue); return head;}//层序序列化和反序列化public static String serialByLevel(Node root){ if(root == null){ return "#!"; } Queue<Node> queue = new LinkedList<Node>(); String ret = root.data+"!"; queue.offer(root); while(!queue.isEmpty()){ Node top = queue.poll(); if(top.left != null){ ret+=top.left.data+"!"; queue.offer(top.left); }else{ ret+="#!"; } if(top.right != null){ ret+=top.right.data+"!"; queue.offer(top.right); }else{ ret+="#!"; } } return ret;}public static Node reconByLevelString(String str){ String[] items = str.split("!"); int index =0; Queue<Node> queue = new LinkedList<Node>();//队列暂存Node Node head = getNode(items[index++]); queue.offer(head); while(!queue.isEmpty()){ Node top = queue.poll(); top.left=getNode(items[index++]); top.right=getNode(items[index++]); if(top.left != null){ queue.offer(top.left); } if(top.right != null){ queue.offer(top.right); } } return head;}private static Node getNode(String string) { if(!string.equals("#")){ return new Node(Integer.parseInt(string)); } return null;}
2、找到二叉树中指定值的最长路径长度
给定一个指定的路径长度,二叉树路径中跨越层数的最大值。
// 在二叉树中找到累加和为指定值的最长路径长度public static int getMaxLength(Node root,int sum){//root-根节点,sum-指定的值 HashMap<Integer,Integer> sumMap = new HashMap<Integer,Integer>(); sumMap.put(0, 0);//路径长度为0的最大路径长度为0 return preOrder(root,sum,0,1,0,sumMap);} private static int preOrder(Node root, int sum, int preSum, int level, int maxLen, HashMap<Integer, Integer> sumMap) {//preSum-记录上次统计的值,level-二叉树层数,maxLen-最大路径长度,sumMap-中间变量保存队列 if(root == null){ return maxLen; } int curLen = preSum + root.data; if(!sumMap.containsKey(curLen)){ sumMap.put(curLen, level); } if(sumMap.containsKey(curLen-sum)){ maxLen = Math.max(level-sumMap.get(curLen-sum), maxLen); } maxLen=preOrder(root.left,sum,curLen,level+1,maxLen,sumMap); maxLen=preOrder(root.right,sum,curLen,level+1,maxLen,sumMap); return maxLen;}
3、找到二叉树中最大的二叉搜索子树
在二叉树中找到最大的二叉搜索子树,并返回该二叉树搜索子树的头结点。
// 找到二叉树中最大的搜索二叉子树 public static Node getMaxSub(Node root){ if(root == null){ return null; } int[] recorde = new int[3]; return posOrder(root,recorde); } private static Node posOrder(Node root, int[] recorde) { /* 二叉树后序遍历解决问题。 recorde记录中间信息,0号位置记录节点个数,1号位置记录最小值,2号位置记录最大值。 */ if(root == null){ recorde[0]=0; recorde[1]=Integer.MAX_VALUE; recorde[2]=Integer.MIN_VALUE; return null; } int data = root.data; Node left = root.left; Node right = root.right; Node lBST = posOrder(left,recorde); int lsize = recorde[0]; int lmin = recorde[1]; int lmax = recorde[2]; Node rBST = posOrder(right,recorde); int rsize = recorde[0]; int rmin = recorde[1]; int rmax = recorde[2]; recorde[1]=Math.min(lmin,data); recorde[2]=Math.max(rmax, data); if(left == lBST && right ==rBST && data>lmax && data<rmin){ recorde[0]=lsize+rsize +1; return root; } recorde[0]=Math.max(lsize, rsize); return lsize >rsize?lBST:rBST; }
4、层序打印
//顺序层序打印 public static void printByLevel(Node root){ if(root == null){ System.out.println("#"); } Queue<Node> queue = new LinkedList<Node>(); queue.offer(root); Node last = root; Node nlast = root; while(!queue.isEmpty()){ Node item = queue.poll(); System.out.print(item.data+" "); if(item.left != null){ nlast = item.left; queue.offer(item.left); } if(item.right != null){ nlast = item.right; queue.offer(item.right); } if(item == last){ System.out.println(); last = nlast; } } } //ZigZag方式层序打印二叉树 public static void printByLevelZig(Node root){ if(root == null){ System.out.println("#"); } Queue<Node> queue = new LinkedList<Node>(); Queue<Integer> tmp = new LinkedList<Integer>(); queue.offer(root); Node last = root; Node nlast = root; boolean flag = true; while(!queue.isEmpty()){ Node item = queue.poll(); //System.out.print(item.data+" "); tmp.offer(item.data); if(item.left != null){ nlast = item.left; queue.offer(item.left); } if(item.right != null){ nlast = item.right; queue.offer(item.right); } if(item == last){ pirntQueue(tmp,flag); flag = !flag; last = nlast; } } } private static void pirntQueue(Queue<Integer> tmp,boolean flag) { if(flag){ while(!tmp.isEmpty()){ System.out.print(tmp.poll()+" "); } }else{ Object[] arry = new Object[tmp.size()]; arry=tmp.toArray(); int length = arry.length; for(int i=0; i<length;i++){ System.out.print((int)arry[length-1-i]+" "); } tmp.clear(); } System.out.println(); }
5、搜索二叉树中两个错误的节点
//调整搜索二叉树中两个错误的节点 public static Node[] getTwoErrNodes(Node root){ /* 中序遍历方式,找到局部逆序的两个位置,找到两个错误节点。 */ Node[] errs = new Node[2]; if(root == null){ return errs; } Stack<Node> stack = new Stack<Node>(); Node pre = null; while(!stack.isEmpty() || root !=null){ if(root != null){ stack.push(root); root = root.left; }else{ root = stack.pop(); if(pre != null && pre.data > root.data){ errs[0]=errs[0]==null?pre:errs[0]; errs[1]=root; } pre=root; root=root.right; } } return errs; }
6、判断二叉树r1是否包含二叉树r2的全部拓扑结构
//判断二叉树r1是否包含二叉树r2的全部拓扑结构 public static boolean contains(Node r1,Node r2){ /* 递归方式解决问题,将问题转化为父节点和子节点问题。然后,针对左子树和右子树去解决问题。 */ if(r1 != null) return check(r1,r2)||contains(r1.left,r2)||contains(r1.right,r2); else return false; } private static boolean check(Node r1, Node r2) { if(r2 == null){ return true; } if(r1 == null || r1.data != r2.data){ return false; } return check(r1.left,r2.left) && check(r1.right,r2.right); }
0 0
- 二叉树相关面试题目之实例总结
- 二叉树相关面试题目总结
- 二叉树的面试题目总结
- 面试大总结之二:Java搞定面试中的二叉树题目
- 面试大总结之二:Java搞定面试中的二叉树题目
- 面试大总结之二:Java搞定面试中的二叉树题目
- 面试大总结之二:Java搞定面试中的二叉树题目
- 面试大总结:Java搞定面试中的二叉树题目
- 二叉树 面试题目
- 二叉树相关题目
- 二叉树相关题目
- 二叉树相关题目
- 面试中所有二叉树题目总结(java版)
- 面试中所有二叉树题目总结(java版)
- 【二叉树】常用处理与leetcode相关题目总结
- [Leetcode][二叉树]相关题目汇总/分析/总结
- 面试中的二叉树题目
- 面试题目集锦--二叉树
- Java栈数据结构的实现方式
- SQL Server无法远程连接
- 2016-8-14 笔记
- setPageTransformer几个特效
- 实习问题小总结
- 二叉树相关面试题目之实例总结
- A. Launch of Collider
- Map集合
- Java技术——Java反射机制分析
- 简单计算器
- Live Archive 3983 Robotruck
- spring mvc支持返回json
- [OS复习]虚拟存储管理技术2
- scollView与ListView结合使用