二叉树问题合集
来源:互联网 发布:知乎 注册信贷分析师 编辑:程序博客网 时间:2024/06/07 00:35
一.前言
二叉树是一种常见的基础数据结构,也是面试笔试中常常碰到的题目.
二叉树(英语:Binary tree)是每个节点最多只有两个分支(不存在分支度大于2的节点)的树结构。通常分支被称作“左子树”和“右子树”。二叉树的分支具有左右次序,不能颠倒。
二叉查找树,可实现对元素的快速查找,对二叉树的理解也是学习其他树结构的基础.
二. 二叉树结构
class BinaryTree{ int value; BinaryTree left; BinaryTree right; public BinaryTree(int value){ this.value = value; this.left = null; this.right = null; }}
三.常见链表问题
1. 树节点个数
2. 树的深度
3. 第K 层节点个数
4. 数的遍历:先序,中序,后序,层序
5. 树的镜像
6. 判断树中是否存在某元素
7. 是否是完全二叉树
8. 二叉树叶子节点个数
9. 判断两颗二叉树结构是否相同
10. 判断是否是平衡二叉树
11. 求二叉树中两个节点的最低公共祖先节点
12. 求二叉树中节点的最大距离
13. 由前序和中序遍历序列重建二叉树
四.题目
1. 树节点个数
1.1 思路
递归
1.2 代码
int getNumOfTree(BinaryTree root) { if (root == null) { return 0; } return 1+getNumOfTree(root.left)+getNumOfTree(root.right);}
2. 树的深度
1.1 思路
递归
1.2 代码
int getDephthOfTree(BinaryTree root) { if (root == null) { return 0; } int leftHeight = getDephthOfTree(root.left); int rightHeight = getDephthOfTree(root.right); return leftHeight>rightHeight?leftHeight+1:rightHeight+1;}
3. 第K 层节点个数
1.1 思路
递归
1.2 代码
private static int getNumberOfKth(BinaryTree root,int k) { if (root == null || k<1) { return 0; } if (k == 1) { return 1; } int kthLeft = getNumberOfKth(root.left, k-1); int kthRight = getNumberOfKth(root.right, k-1); return kthLeft+kthRight;}
4. 数的遍历:先序,中序,后序,层序
1.1 思路
前序,中序,后序采用递归的方法,层序遍历借用队列来完成遍历.
1.2 代码
//前序private static void preOrder(BinaryTree root) { if (root != null) { System.out.print(root.value+" "); preOrder(root.left); preOrder(root.right); }}//中序private static void inOrder(BinaryTree root) { if (root != null) { inOrder(root.left); System.out.print(root.value+" "); inOrder(root.right); }}//后序private static void postOrder(BinaryTree root) { if (root != null) { postOrder(root.left); postOrder(root.right); System.out.print(root.value+" "); }}//层序private static void leverOrder(BinaryTree root) { if (root == null) { return; } Queue<BinaryTree> queue = new LinkedList<>(); queue.add(root); while(!queue.isEmpty()){ BinaryTree pNode = queue.peek(); System.out.print(pNode.value+" "); queue.remove(); if (pNode.left != null) { queue.add(pNode.left); } if (pNode.right != null) { queue.add(pNode.right); } }}
5. 树的镜像
1.1 思路
递归.
1.2 代码
private static BinaryTree mirror(BinaryTree root) { if (root == null) { return null; } BinaryTree left = mirror(root.left); BinaryTree right = mirror(root.right); root.left = right; root.right = left; return root;}
6. 判断树中是否存在某元素
1.1 思路
任选一遍历方法进行查找.
1.2 代码
private static void Find(BinaryTree root,int number) { if (root != null) { if (root.value == number) { System.out.println("Found."); return; } Find(root.left, number); Find(root.right, number); }}
7. 是否是完全二叉树
1.1 思路
使用队列进行遍历,若本层有未满子树,则下一层不应有节点.
1.2 代码
private static boolean isComplete(BinaryTree root) { if (root == null) { return true; } boolean hasNoChild = false; //本层有未满子树,则下一次不应该有节点. boolean result = true; Queue<BinaryTree> queue = new LinkedList<>(); queue.add(root); while(!queue.isEmpty()){ BinaryTree pNode = queue.remove(); if (hasNoChild) { if (pNode.left != null || pNode.right != null) { result = false; break; } }else { if (pNode.left!= null && pNode.right != null) { queue.add(pNode.left); queue.add(pNode.right); }else if (pNode.left == null && pNode.right != null) { result = false; break; }else if(pNode.left != null && pNode.right == null){ hasNoChild = true; //进行下一轮扫描时,右子树为空 queue.add(pNode.left); }else { hasNoChild = true; } } } return result;}
8. 二叉树叶子节点个数
1.1 思路
递归.
1.2 代码
private static int getNumOfLeaf(BinaryTree root) { if (root == null) { return 0; } if (root.left == null && root.right == null) { return 1; } int left = getNumOfLeaf(root.left); int right = getNumOfLeaf(root.right); return left+right;}
9. 判断两棵二叉树结构是否相同
1.1 思路
递归.
1.2 代码
private static boolean isCommon(BinaryTree root1, BinaryTree root2) { if (root1 == null && root2 == null) { return true; }else if (root1 == null || root2 == null) { return false; } boolean left = isCommon(root1.left, root2.left); boolean right = isCommon(root1.right, root2.right); return (left&&right);}
10. 判断是否是平衡二叉树
1.1 思路
递归.
1.2 代码
private static boolean isAVL(BinaryTree root) { if (root == null) { return true; } int left_height = getDephthOfTree(root.left); int right_height = getDephthOfTree(root.right); int diff = left_height - right_height; if (diff <-1 || diff > 1) { return false; } return isAVL(root.left) && isAVL(root.right);}
11. 求二叉树中两个节点的最低公共祖先节点
1.1 思路
从root开始遍历,如果n1和n2中的任一个和root匹配,那么root就是LCA。 如果都不匹配,则分别递归左、右子树,如果有一个 key(n1或n2)出现在左子树,并且另一个key(n1或n2)出现在右子树,则root就是LCA. 如果两个key都出现在左子树,则说明LCA在左子树中,否则在右子树。
1.2 代码
private static BinaryTree findLCA(BinaryTree root, BinaryTree pNode1, BinaryTree pNode2) { if (root == null) { return null; } if (root.value == pNode1.value || root.value == pNode2.value) { return root; } BinaryTree left_lca = findLCA(root.left, pNode1, pNode2); BinaryTree right_lca = findLCA(root.right, pNode1, pNode2); if (left_lca != null && right_lca != null) { return root; } return (left_lca !=null)?left_lca:right_lca;}
12. 求二叉树中节点的最大距离
1.1 思路
递归.
1.2 代码
//最大距离Max(左子树最大距离,右子树最大距离,左子树节点到根节点的最大距离+右子树节点到根节点的最大距离)private static int height(BinaryTree root) { if (root == null) { return 0; } int heightLeft = height(root.left); int heightRight = height(root.right); return heightLeft>heightRight?(heightLeft+1):(heightRight+1);}private static int getMaxDistance(BinaryTree root) { if (root == null) { return 0; }else if (root.left == null && root.right == null) { return 0; } int dis = max(height(root.left)+height(root.right),getMaxDistance(root.left),getMaxDistance(root.right)); if (maxDis <dis) { maxDis = dis; } return dis;}private static int max(int a, int b, int c) { int temp = a>b?a:b; return temp>c?temp:c;}
13. 由前序和中序遍历序列重建二叉树
1.1 思路
递归.
1.2 代码
private static BinaryTree buildTree(int[] preOrder, int startPre, int endPre, int[] inOrder, int startIn, int endIn) { if ((endPre-startPre) != (endIn-startIn)) { return null; } if (preOrder == null || inOrder == null || preOrder.length<1 || inOrder.length <1) { return null; } int rootValue = preOrder[startPre]; BinaryTree root = new BinaryTree(rootValue); if ((startPre == endPre) && (startIn == endIn)) { return root; } int rootIdx = startIn; while (rootIdx <=endIn && inOrder[rootIdx]!=rootValue){ rootIdx ++; } if (rootIdx>endIn) { return null; } int leftLength = rootIdx-startIn; int leftPreorderLeft = leftLength + startPre; if (leftLength>0) { root.left = buildTree(preOrder, startPre+1, leftPreorderLeft, inOrder, startIn, rootIdx-1); } if (leftLength<endPre -startPre) { root.right = buildTree(preOrder, leftPreorderLeft+1, endPre, inOrder, rootIdx+1, endIn); } return root;}
参考文献
- 轻松搞定面试中的二叉树题目
- <剑指offer>
- 寻找二叉树两个节点的最低公共祖先
- 二叉树问题合集
- Codevs 二叉树遍历问题 合集
- leetcode二叉树问题合集
- 二叉树面试题合集
- 二叉树----二叉树面试题合集
- 二叉树----二叉树面试题合集
- 二叉树操作合集(陆续更新)
- 【day-14】二叉树-剑指offer难题合集
- 数据结构之二叉树的遍历算法合集
- Leetcode Tree Problem 树问题合集
- js问题合集
- session问题合集
- 小问题合集
- js问题合集
- 问题合集
- 背包问题合集
- 编码问题合集
- 汉诺塔问题合集
- 4.RPC框架的简单实现(服务发布-ServiceBean实现)
- Hdu-6200 mustedge mustedge mustedge(动态树+并查集)
- 菜鸟学设计模式----责任链模式
- 下拉选择框,PopupWindow的使用
- SpringMVC——静态资源访问之<mvc:annotation-driven/>与<mvc:default-servlet-handler/>
- 二叉树问题合集
- 括号配对问题
- platform平台device和driver如何匹配
- 预编译的作用和目的
- 简述page指令的各个属性的值
- [中等] UVa OJ 10003 Cutting Sticks 动态规划
- Android animation属性动画
- Selenium with Python中文翻译(四)
- 生物信息学-批量上传文件