二叉树题目
2013-10-17 19:51
302 查看
1. 二叉树的三种遍历方式
先序遍历:节点 -> left子节点(包括其子树)-> right子节点(包括其子树);
后序遍历:left子节点(包括其子树)-> right子节点(包括其子树)-> 节点;
中序遍历:left子节点(包括其子树)-> 节点 -> right子节点。
2. 怎样从根开始逐层打印二叉树结点数据
其实就是广度优先遍历(BFS)的思想。
使用一个队列queue,将root入队;
若queue不为空,出队一个节点,并将此节点两个儿子按从左到右顺序入栈;
则出队顺序即为逐层遍历顺序。
3. 如何判断一颗二叉树是否平衡二叉树?
平衡二叉树定义:任意节点的左右子树深度相差不超过1。
只要当前节点root的left和right深度差不超过1,就递归判断left和right是否也符合条件,直到left或right为null,这意味着他们的深度为0,能走到这一步,前面必然都符合条件,所以整个二叉树都符合条件。
需要两个栈,在递归遍历寻找两个节点的同时,将从根到两个节点的路径分别压栈(由于是递归,两节点父节点最先入栈,根最后入栈);
同时pop两个元素,如果相等,则继续pop,直到不等,则之前相等的元素节点就是最近共同父节点。
此解法需要两个辅助栈。
注意这里是二叉树而不是二叉查找树,如果是二叉查找树,则不需要递归查找,直接往下遍历,直到分叉位置,就是最近共同父节点。
5. 如何不用递归实现二叉树的三种遍历。
先序遍历
后序遍历
中序遍历
6. 在二叉树中找出和为某一值的所有路径
当访问某一个节点时,把该节点添加到路径上,并累加当前节点的值。如果当前节点为叶节点并且当前路径的和刚好等于输入的整数,则当前的路径符合要求,把它打印出来。如果当前节点不是叶节点,则继续访问它的子节点。当前节点访问结束后,递归函数自动回到父节点。因此,函数退出之前要在路径上删除当前节点并减去当前节点的值,以确保返回父节点时路径刚好是根节点后父节点的路径。不难看出保存路径的数据结构实际上是一个栈结构。
7. 编写一个程序,把一个有序整数数组放到二叉树中
构造一个完全二叉树,让数组第一个元素小标为1,则有左儿子是2i, 右儿子是 2i+1,这样是平衡的。
8. 判断整数序列是不是二叉查找树的后序遍历结果
在后序遍历的序列中,最后一个元素为树的根节点。从头开始扫描这个序列,比根节点小的元素都应该位于序列的左半部分,从第一个大于根节点开始到根节点前面一个元素为止,所有元素都大于根节点,因为这部分元素对应的是树的右子树。根据这样划分,把序列分为左右两部分,递归的确认序列的左右两部分是不是都是二叉查找树。
9. 求二叉树的镜像
利用遍历二叉树的方法,把访问操作修改为交换左右节点的逻辑即可。
10. 一棵二叉查找树,令 f = (最大值 + 最小值)/2,设计一个算法,找出距离 f 值最近,大于 f 值的节点。复杂度如果是O(n^2)则不得分。
11. 把二叉查找树转变成排序的双向链表。
就是树的中序遍历。
先序遍历:节点 -> left子节点(包括其子树)-> right子节点(包括其子树);
后序遍历:left子节点(包括其子树)-> right子节点(包括其子树)-> 节点;
中序遍历:left子节点(包括其子树)-> 节点 -> right子节点。
2. 怎样从根开始逐层打印二叉树结点数据
其实就是广度优先遍历(BFS)的思想。
使用一个队列queue,将root入队;
若queue不为空,出队一个节点,并将此节点两个儿子按从左到右顺序入栈;
则出队顺序即为逐层遍历顺序。
3. 如何判断一颗二叉树是否平衡二叉树?
平衡二叉树定义:任意节点的左右子树深度相差不超过1。
只要当前节点root的left和right深度差不超过1,就递归判断left和right是否也符合条件,直到left或right为null,这意味着他们的深度为0,能走到这一步,前面必然都符合条件,所以整个二叉树都符合条件。
//先编写一个递归计算二叉树深度的函数getDepth,利用递归实现 public static int getDepth(Node root){ if(root == null) return 0; int leftDepth = getDepth(root.left); int rightDepth = getDepth(root.right); return (leftDepth > rightDepth? leftDepth : rightDepth) + 1; } public static boolean isBalance(Node root){ if(root == null) return true; int leftDepth = getDepth(root.left); int rightDepth = getDepth(root.right); int distance = leftDepth > rightDepth ? leftDepth-rightDepth : rightDepth - leftDepth; if(distance > 1) return false; else return isBalance(root.left) && isBalance(root.right); }4. 设计一个算法,找出二叉树上任意两个节点的最近共同父节点,复杂度如果是O(N^2)则不得分。
需要两个栈,在递归遍历寻找两个节点的同时,将从根到两个节点的路径分别压栈(由于是递归,两节点父节点最先入栈,根最后入栈);
同时pop两个元素,如果相等,则继续pop,直到不等,则之前相等的元素节点就是最近共同父节点。
此解法需要两个辅助栈。
注意这里是二叉树而不是二叉查找树,如果是二叉查找树,则不需要递归查找,直接往下遍历,直到分叉位置,就是最近共同父节点。
//递归寻找节点,并将路径存入stack中 pubilc static boolean getPositionByNode(Node root, Node node, Stack<E> stack){ if(root == null) return false; //递归的基准情况 if(root == node){ stack.push(root); return true; } //递归调用 if(getPositionByNode(root.left, node, stack) || getPositionByNode(root.right, node, stack)){ stack.push(root); return true; } return false; } public static Node findParentNode(Node root, Node node1, Node node2){ Stack stack1 = new Stack(); getPositionByNode(node1, stack1); Stack stack2 = new Stack(); getPositionByNode(node2, stack2); Node temp = null; //两者不相等,则同时弹栈,但是要记录弹栈元素 while(stack1.peek() != stack2.peek()){ temp = stack1.pop(); stack2.pop(); } return temp; }
5. 如何不用递归实现二叉树的三种遍历。
先序遍历
//先序遍历 public static void preOrder(Node root){ Stack stack = new Stack(); Node node = root; while(node != null || stack.size() > 0){ //压入所有左节点,压入前打印 while(node != null){ System.out.println(node.data); stack.push(node); node = node.left; } if(stack.size() > 0){ node = stack.pop(); node = node.right; } } }
后序遍历
//后序遍历 public static void postOrder(Node root){ Stack stack = new Stack(); Node node = root; Node prev = node; while(node != null || stack.size() > 0){ //压入所有左节点 while(node != null){ stack.push(node); node = node.left; } if(stack.size() > 0){ Node temp = stack.peek().right; //如果右节点是null或者刚访问过 if(temp == null || temp == prev){ node = stack.pop(); System.out.println(node.data); prev = node; node = null; }else{ node = temp; } } } }
中序遍历
//中序遍历 public static void inOrder(Node root){ Stack stack = new Stack(); Node node = root; while(node != null || stack.size() > 0){ //压入所有左节点 while(node != null){ stack.push(node); node = node.left; } if(stack.size() > 0){ node = stack.pop(); System.out.println(node.data); node = node.right(); } } }
6. 在二叉树中找出和为某一值的所有路径
当访问某一个节点时,把该节点添加到路径上,并累加当前节点的值。如果当前节点为叶节点并且当前路径的和刚好等于输入的整数,则当前的路径符合要求,把它打印出来。如果当前节点不是叶节点,则继续访问它的子节点。当前节点访问结束后,递归函数自动回到父节点。因此,函数退出之前要在路径上删除当前节点并减去当前节点的值,以确保返回父节点时路径刚好是根节点后父节点的路径。不难看出保存路径的数据结构实际上是一个栈结构。
7. 编写一个程序,把一个有序整数数组放到二叉树中
构造一个完全二叉树,让数组第一个元素小标为1,则有左儿子是2i, 右儿子是 2i+1,这样是平衡的。
8. 判断整数序列是不是二叉查找树的后序遍历结果
在后序遍历的序列中,最后一个元素为树的根节点。从头开始扫描这个序列,比根节点小的元素都应该位于序列的左半部分,从第一个大于根节点开始到根节点前面一个元素为止,所有元素都大于根节点,因为这部分元素对应的是树的右子树。根据这样划分,把序列分为左右两部分,递归的确认序列的左右两部分是不是都是二叉查找树。
9. 求二叉树的镜像
利用遍历二叉树的方法,把访问操作修改为交换左右节点的逻辑即可。
10. 一棵二叉查找树,令 f = (最大值 + 最小值)/2,设计一个算法,找出距离 f 值最近,大于 f 值的节点。复杂度如果是O(n^2)则不得分。
//最小最大节点分别在最左下与最右下节点 public static Node find(Node root){ Node min = findMinNode(root); Node max = findMaxNode(root); double find = (double)(min.data + max.data)/2.0; return findNode(root, find); } //最小节点 public static Node findMinNode(Node root){ Node min = root; ] while(min.left != null) min = min.left; return min; } //最大节点 public static Node finMaxNode(Node root){ Node max = root; while(max.right != null) max = max.right; return max; } //寻找节点,O(logN) public static findNode(Node root, double mid){ //如果小于等于,则从右边找一个最小值 if(root.data <= mid){ if(root.right == null) return root; Node find = findNode(root.right, mid); //不一定找得到 return find.data < mid ? root : find; } //如果大于,则找到left else{//root.data > find if(root.left == null) return root; Node find = findNode(root.left, mid); //不一定找到 return find.data < mid ? root:find; } }
11. 把二叉查找树转变成排序的双向链表。
就是树的中序遍历。
相关文章推荐
- 二叉树题目集锦1
- 题目:在二叉树中给出两个已知结点,求这两个结点的最低公共祖先
- 轻松搞定面试中的二叉树题目
- 二叉树相关题目
- 轻松搞定面试中的二叉树题目
- 轻松搞定面试中的二叉树题目
- 二叉树题目
- 轻松搞定面试中的二叉树题目
- 一篇文章搞定面试中的二叉树题目(java实现)
- 【LeetCode题目记录-11】判断二叉树是否是镜像的(对称的)
- 【转】轻松搞定面试中的二叉树题目
- 算法题目-二叉树前中后序遍历
- 二叉树题目汇总
- 数据结构课程设计题目四_二叉树
- 面试中所有二叉树题目总结(java版)
- [实战演练]蜻蜓FM2014年校招笔试题目 - 规则二叉树
- 二叉树题目整理(一)
- 【剑指Offer面试编程题】题目1385:重建二叉树--九度OJ
- 【剑指Offer面试编程题】题目1368:二叉树中和为某一值的路径--九度OJ
- 题目1113:二叉树