二叉树问题合集

来源:互联网 发布:知乎 注册信贷分析师 编辑:程序博客网 时间: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;}

参考文献

  1. 轻松搞定面试中的二叉树题目
  2. <剑指offer>
  3. 寻找二叉树两个节点的最低公共祖先
原创粉丝点击