二叉树 面试 JAVA
来源:互联网 发布:照片打印排版软件 编辑:程序博客网 时间:2024/05/03 06:17
package interview.src;import java.lang.annotation.Retention;import java.util.ArrayList;import java.util.Arrays;import java.util.LinkedList;import java.util.List;import java.util.Queue;import java.util.Scanner;import java.util.Stack;//定义二叉树节点class BinaryTreeNode{int data;BinaryTreeNode left;BinaryTreeNode right;public BinaryTreeNode() {// TODO Auto-generated constructor stub}public BinaryTreeNode(int data) {this.data=data;left=null;right=null;}}public class BinaryTree_Summary {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub/* 1 / \ 2 3 / \ \ 4 5 6 */ //BinaryTreeNode r1=new BinaryTreeNode(1);//BinaryTreeNode r2=new BinaryTreeNode(2);//BinaryTreeNode r3=new BinaryTreeNode(3);//BinaryTreeNode r4=new BinaryTreeNode(4);//BinaryTreeNode r5=new BinaryTreeNode(5);//BinaryTreeNode r6=new BinaryTreeNode(6);////r1.left=r2;//r1.right=r3;//r2.left=r4;//r2.right=r5;//r3.right=r6;BinaryTree_Summary bt=new BinaryTree_Summary();//bt.preOrder(r1);//bt.inorderTraversal(r1);//bt.postOrderTraversal(r1);//bt.levelTraversal(r1);//bt.levelTaversalRec(r1); /* 10 / \ 6 14 / \ \ 4 8 16 / 0 */ BinaryTreeNode r1 = new BinaryTreeNode(10); BinaryTreeNode r2 = new BinaryTreeNode(6); BinaryTreeNode r3 = new BinaryTreeNode(14); BinaryTreeNode r4 = new BinaryTreeNode(4); BinaryTreeNode r5 = new BinaryTreeNode(8); BinaryTreeNode r6 = new BinaryTreeNode(16); BinaryTreeNode r7 = new BinaryTreeNode(0); r1.left = r2; r1.right = r3; r2.left = r4; r2.right = r5; r3.right = r6; r4.left = r7; BinaryTreeNode ret=bt.convert2LinkedListRec(r1);while (ret !=null) {System.out.print(ret.data+" ");ret=ret.right;}//BinaryTreeNode ret1=bt.convert2LinkedList(r1);//while (ret1 !=null) {//System.out.print(ret1.data+" ");//ret1=ret1.right;//}//while (ret1 !=null) {//System.out.print(ret1.data+" ");//ret1=ret1.left;//}}//1.创建二叉树public BinaryTreeNode createTree(BinaryTreeNode root){ int data;Scanner scanner = new Scanner(System.in); data = scanner.nextInt(); root=new BinaryTreeNode();//创建根节点 root.data=data; root.left=createTree(root.left);//递归,创建左子树 root.right=createTree(root.right);//递归,创建右子树 return root; //返回树的根节点 }//2.求二叉树镜像,递归public void mirrorRec(BinaryTreeNode root){if (root==null) {return;}if ((root.left==null) &&(root.right==null)){return;}BinaryTreeNode temp=root.left; //交换左右孩子root.left=root.right;root.right=temp;mirrorRec(root.left);mirrorRec(root.right);}//2.求二叉树镜像,迭代//3.求二叉树节点数,递归----null返回0,然后把左右子树的size加上即可public int getNodeNumRec( BinaryTreeNode root) {if (root ==null) {return 0;}return getNodeNumRec(root.left) + getNodeNumRec(root.right)+1;}//3.求二叉树节点数,迭代---基本思想同LevelOrderTraversal, 即用一个Queue,在Java里面可以用LinkedList来模拟public int getNodeNum(BinaryTreeNode root) {if (root==null) {return 0;}Queue<BinaryTreeNode> que=new LinkedList<BinaryTreeNode>();que.offer(root);//根节点入队int cnt=0;//节点数目while (!que.isEmpty()) {BinaryTreeNode node=que.poll();//不为空,出队列cnt++;//出一个,计一个if (node.left!=null) { //先左后右入队que.offer(node.left);}if (node.right!=null) {que.offer(node.right);}}return cnt;}//4.求二叉树深度,递归public int getDepthRec(BinaryTreeNode root) {if (root ==null) {return 0;}int depthleft=getDepthRec(root.left);int depthright=getDepthRec(root.left);return depthleft > depthright? (depthleft+1):(depthright+1);}//4.求二叉树深度,迭代public int getDepth(BinaryTreeNode root) {if (root==null) {return 0;}BinaryTreeNode dum=new BinaryTreeNode(); // 使用DummyNode来区分不同的层Queue<BinaryTreeNode> que=new LinkedList<BinaryTreeNode>();que.offer(root);//根节点入队que.offer(dum);int depth=-1;while (!que.isEmpty()) {BinaryTreeNode node=que.poll();if (node==dum) { //层结束标志,深度+1depth++; if (!que.isEmpty()) { // 如果下一层不是为空,则应该在尾部加DummyNode.que.offer(dum);}}if (node.left!=null) {que.offer(node.left);}if (node.right!=null) {que.offer(node.right);}}return depth;}//5.前序遍历,递归public void preOrderRec(BinaryTreeNode root) {if (root==null) {return;}System.out.print(root+" ");preOrderRec(root.left);preOrderRec(root.right);}//5.迭代,前序遍历---把根节点存在stack中。 public void preOrder(BinaryTreeNode root) {if (root==null) {return;}Stack<BinaryTreeNode> stack=new Stack<BinaryTreeNode>();stack.push(root);//根节点入栈while (!stack.isEmpty()) {BinaryTreeNode node=stack.pop();System.out.print(node.data+" ");//输出节点// 先压入右节点,再压入左节点,这样就可以先弹出左节点。 if (node.right!=null) {stack.push(node.right);}if (node.left!=null) {stack.push(node.left);}}System.out.println();}//6.中序遍历 ,递归public void inorderTraversalRec(BinaryTreeNode root) {if (root==null) {return;}inorderTraversalRec(root.left);System.out.print(root.data+" ");inorderTraversal(root.right);} /** * 中序遍历迭代解法 ,用栈先把根节点的所有左孩子都添加到栈内, * 然后输出栈顶元素,再处理栈顶元素的右子树 * http://www.youtube.com/watch?v=50v1sJkjxoc * * 还有一种方法能不用递归和栈,基于线索二叉树的方法,较麻烦以后补上 * http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/ *///6.迭代,中序遍历public void inorderTraversal(BinaryTreeNode root) {if (root==null) {return;}Stack<BinaryTreeNode> stack=new Stack<BinaryTreeNode>();BinaryTreeNode node=root;while (true) {// 把当前节点的左节点都push到栈中while (node!=null) {stack.push(node);node=node.left; }if (stack.isEmpty()) {break;} // 因为此时已经没有左孩子了,所以输出栈顶元素node=stack.pop();System.out.print(node.data+" ");// 处理右子树 node=node.right; //再处理右节点}System.out.println();}//7.后序遍历 ,递归public void postOrderTraversalRec(BinaryTreeNode root) {if (root==null) {return;}postOrderTraversalRec(root.left);postOrderTraversalRec(root.right);System.out.print(root.data+" ");}/** * 后序遍历迭代解法 * http://www.youtube.com/watch?v=hv-mJUs5mvU * http://blog.csdn.net/tang_jin2015/article/details/8545457 * 从左到右的后序, 与从右到左的前序的逆序是一样的, 用另外一个栈进行翻转即可 */ //7.迭代,后序遍历 public void postOrderTraversal(BinaryTreeNode root) {if (root==null) {return;}Stack<BinaryTreeNode> stack=new Stack<BinaryTreeNode>();Stack<BinaryTreeNode> stack2=new Stack<BinaryTreeNode>();//翻转stack.push(root);//根节点入栈while (!stack.isEmpty()) {BinaryTreeNode node=stack.pop();stack2.push(node); //这里跟前序不一样,不打印,而是存到stack2中//先左后右,从右到左的前序 逆序if (node.left!=null) {stack.push(node.left);}if (node.right!=null) {stack.push(node.right);}}//弹出stack2中的元素,即从右往左前序遍历的逆序while (!stack2.isEmpty()) {System.out.print(stack2.pop().data+" ");}System.out.println();}//8.层次遍历 ,递归public void levelTaversalRec(BinaryTreeNode root) {ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>();levelTaversalVisitRec(root,0,list);//递归调用System.out.print(list);//打印遍历结果}private void levelTaversalVisitRec(BinaryTreeNode root, int level,ArrayList<ArrayList<Integer>> list) {// TODO Auto-generated method stubif (root==null) {return;}if (level >= list.size()) { // 如果ArrayList的层数不够用, 则新添加一层 list.add(new ArrayList<Integer>()); }list.get(level).add(root.data);// visit 当前节点 levelTaversalVisitRec(root.left, level+1, list);// 将左子树, 右子树添加到对应的层。levelTaversalVisitRec(root.right, level+1, list);}/* * 迭代,层次遍历二叉树(按层次从上往下,从左往右)迭代 * 其实就是广度优先搜索,使用队列实现。队列初始化,将根节点压入队列。当队列不为空,进行如下操作:弹出一个节点 * ,访问,若左子节点或右子节点不为空,将其压入队列 * *///8.迭代,层次遍历 ---按层次从上往下,从左往右public void levelTraversal(BinaryTreeNode root) {Queue<BinaryTreeNode> que=new LinkedList<BinaryTreeNode>();que.offer(root);//根节点入队while(!que.isEmpty()){BinaryTreeNode node=que.poll();System.out.print(node.data+" ");if (node.left!=null) { //队列是先进先出,所以要左孩子先进que.offer(node.left);}if (node.right!=null) {que.offer(node.right);}}System.out.println();}//9.由前序和中序遍历序列,重建二叉树public BinaryTreeNode rebuildTreeRec(List<Integer> pre,List<Integer> in) {if (pre==null || in==null) {return null;}if (pre.size()==0 || in.size()==0) {return null;}//根节点是前序的第一个元素BinaryTreeNode root=new BinaryTreeNode(pre.get(0));// 获得在 inOrder中,根的位置 ,也是左子树节点的个数int rootIndex=in.indexOf(pre.get(0));List<Integer> preLeft =pre.subList(1, rootIndex+1);// [ )List<Integer> preRight =pre.subList(rootIndex+1, pre.size());List<Integer> inLeft =in.subList(0, rootIndex);List<Integer> inRight =in.subList(rootIndex+1, in.size()); // 通过 Rec来调用生成左右子树。 root.left =rebuildTreeRec(preLeft, inLeft);root.right=rebuildTreeRec(preRight, inRight);return root;}//10.推荐递归,将 二叉查找树 变为有序的双向链表,不能创建新节点,只调整指针。/** * 查找树的结点定义如下: 以中序遍历二叉搜索树时,其遍历的结点就是有序的。 将根结点的左子树和右子树转换为有序的双向链表, 然后根节点的left指针指向左子树结果的最后一个结点, 同时左子树最后一个结点的right指针指向根节点; 根节点的right指针指向右子树结果的第一个结点, 同时右子树第一个结点的left指针指向根节点。 * */ public BinaryTreeNode convert2LinkedListRec (BinaryTreeNode root) {return convert2LinkedListRecHelper(root)[0];//最小的节点即是链表的头}private BinaryTreeNode[] convert2LinkedListRecHelper(BinaryTreeNode root) {// TODO Auto-generated method stubBinaryTreeNode[] ret=new BinaryTreeNode[2]; /* * 临时变量 * ret[0] 代表左指针 * ret[1] 代表右指针 * */ ret[0]=null;ret[1]=null;if (root==null) {return ret;}if (root.left !=null) {BinaryTreeNode[] left= convert2LinkedListRecHelper(root.left);left[1].right =root; // 调整关系,将左子树的尾节点(即返回子树的右left[1])连接到根 root.left =left[1];ret[0] =left[0]; //最小的节点,左}else {ret[0]=root; // 左节点返回当前节点root.}if (root.right !=null) {BinaryTreeNode[] right= convert2LinkedListRecHelper(root.right);right[0].left = root; // 调整关系,将右子树的头节点(即返回子树的左left[0])连接到根 root.right = right[0]; ret[1] = right[1]; //最大的节点,右}else { ret[1] = root; // 右节点返回当前节点root. } return ret;}//10.不推荐迭代,溢出,将二叉查找树变为有序的双向链表,不能创建新节点,只调整指针。//类似inOrder traversal的做法 public BinaryTreeNode convert2LinkedList (BinaryTreeNode root) {while (root==null) {return null;}BinaryTreeNode pre =null;Stack<BinaryTreeNode> stack =new Stack<BinaryTreeNode>();BinaryTreeNode node=root;BinaryTreeNode head=null; // 链表头 while (true) {while (node !=null) {stack.push(node);node =node.left;}if (stack.isEmpty()) {break;}node =stack.pop();if (head==null) {head=node;}node.left=pre;if (pre !=null) {pre.right=node;}node=node.right;pre=node;}return root;}//11. 判断二叉树是不是完全二叉树}
0 0
- 二叉树 面试 JAVA
- Java搞定面试中的二叉树题目
- JAVA面试之二叉树问题
- 二叉树面试常考题【JAVA】
- Java搞定面试中的二叉树题目
- 面试中的二叉树题目,java描述
- Java搞定面试中的二叉树题目
- java面试中的二叉树题目汇总
- 二叉树面试总结 算法 java
- 面试大总结:Java搞定面试中的二叉树题目
- 二叉树 面试
- 二叉树--面试加分
- 二叉树面试总结
- 二叉树面试
- 二叉树 面试题目
- Java面试宝典之二叉树的实现
- 面试中所有二叉树题目总结(java版)
- 面试中的二叉树问题总结【Java版】
- 获取当天从0点开始的时间
- 我的ITEYE搬家到csdn
- Java栈的应用检测平衡符号
- WOWb编码
- NSMutableArray
- 二叉树 面试 JAVA
- 谈谈你对多态的理解
- the argument of function in python
- 继承的访问控制--私有继承
- 1.1java简介
- 连载《一个程序猿的生命周期》-33、出差后,导致老板与我的矛盾激化
- JavaScript闭包原理
- 对结对编程的一点感想
- Lua程序语言设计学习-0