二叉树面试题汇总(一)

来源:互联网 发布:长板女生知乎 编辑:程序博客网 时间:2024/05/22 09:56

title: 二叉树面试题汇总(一)
categories: 数据结构
date: 2016-08-18 9:16:00

版权声明:本站采用开放的[知识共享署名-非商业性使用-相同方式共享 许可协议]进行许可

所有文章出现的代码,将会出现在我的github中,名字可以根据类全名来找,我在github中的文件夹也会加目录备注。


计算二叉树的总结点数

树的定义:

public class BinaryTree {    int value;    BinaryTree leftChild;    BinaryTree rightChild;    public BinaryTree(int value) {        super();        this.value = value;    }    public int getValue() {        return value;    }    public void setValue(int value) {        this.value = value;    }    public BinaryTree getLeftChild() {        return leftChild;    }    public void setLeftChild(BinaryTree leftChild) {        this.leftChild = leftChild;    }    public BinaryTree getRightChild() {        return rightChild;    }    public void setRightChild(BinaryTree rightChild) {        this.rightChild = rightChild;    }}

递归法

思路:

  • 判断传过来的根节点是否为空,若为空直接返回0

  • 把左子树+右子树总数再加上根节点,就是该树的总结点数

  • 那么左子节点总数和右子节点总数怎样使用递归方式求?

  • 每次把递归到的节点的左节点总数+右节点总数+1,其中1是指当前根节点,这样每次递归得到的结果都是当前节点中子节点的总数+当前节点

代码实现:

public class CountNodes {    /**     * 使用递归统计树的节点总数     *      * @param root     * @return     */    public static int getCount(BinaryTree root) {        // 判断根节点是否为空        if (root == null) {            // 为空返回0            return 0;        } else {            // 不为空,            // 递归调用 左子树+右子树            return getCount(root.getLeftChild())                    + getCount(root.getRightChild()) + 1;        }    }

图解:






测试代码:

public class BinaryTreeCountNodesTest {    public static void main(String[] args) {        BinaryTree n1 = new BinaryTree(1);        BinaryTree n2 = new BinaryTree(2);        BinaryTree n3 = new BinaryTree(3);        BinaryTree n4 = new BinaryTree(4);        BinaryTree n5 = new BinaryTree(5);        BinaryTree n6 = new BinaryTree(6);        n1.setLeftChild(n2);        n1.setRightChild(n3);        n2.setLeftChild(n4);        n2.setRightChild(n5);        n3.setRightChild(n6);        System.out.println(CountNodes.getCount(n1));    }}

运行结果:

循环

思路:

  • 通过把节点存入某个“容器”中实现,这里考虑到要存进去的节点立刻能用,所以考虑队列

  • 判断根节点是否为空,为空返回0;否则存进队列中

  • 定义一个变量count,来记录节点的总数

  • 接下来就是循环判断队列是否为空了

  • 若不为空,首先得到队首的节点,即把头节点出队。

  • 判断头节点的左节点是否为空,不为空,count+1,并且把左节点加入队列

  • 判断头节点的右节点是否为空,不为空,count+1,并且把右节点加入队列

  • 最后返回count

代码实现:

public static int getCountByIteration(BinaryTree root) {        int count = 1;        if (root == null) {            return 0;        }        // 创建一个队列,先把传进来的root节点加到队列中        Queue<BinaryTree> binaryTrees = new LinkedList<BinaryTree>();        binaryTrees.add(root);        // 当队列不为空的时候循环        while (!binaryTrees.isEmpty()) {            // 把队头节点出列            BinaryTree currentNode = binaryTrees.remove();            // 判断有没有子节点,有就把子节点存入队列,并把count加一            if (currentNode.getLeftChild() != null) {                count++;                binaryTrees.add(currentNode.getLeftChild());            }            if (currentNode.getRightChild() != null) {                count++;                binaryTrees.add(currentNode.getRightChild());            }        }        // 返回总数        return count;    }

测试代码:

public class BinaryTreeCountNodesTest {    public static void main(String[] args) {        BinaryTree n1 = new BinaryTree(1);        BinaryTree n2 = new BinaryTree(2);        BinaryTree n3 = new BinaryTree(3);        BinaryTree n4 = new BinaryTree(4);        BinaryTree n5 = new BinaryTree(5);        BinaryTree n6 = new BinaryTree(6);        n1.setLeftChild(n2);        n1.setRightChild(n3);        n2.setLeftChild(n4);        n2.setRightChild(n5);        n3.setRightChild(n6);        System.out.println(CountNodes.getCountByIteration(n1));    }}

运行结果:

计算二叉树的深度

递归

思路:

  • 分别得到左右子节点的深度,取较大值+1 就是该二叉树的深度

  • 其中每个节点都可能有左右子节点

代码实现:

public static int countDeepness(BinaryTree root) {        // 判断根节点是否为空        // 为空返回0        if (root == null)            return 0;        int left = countDeepness(root.getLeftChild());        int right = countDeepness(root.getRightChild());        // 返回左子节点和右子节点较大数+1,1指当前节点        return Math.max(left, right) + 1;    }

图解:

测试代码:

public class BinaryTreeCountNodesTest {    public static void main(String[] args) {        BinaryTree n1 = new BinaryTree(1);        BinaryTree n2 = new BinaryTree(2);        BinaryTree n3 = new BinaryTree(3);        BinaryTree n4 = new BinaryTree(4);        BinaryTree n5 = new BinaryTree(5);        BinaryTree n6 = new BinaryTree(6);        n1.setLeftChild(n2);        n1.setRightChild(n3);        n2.setLeftChild(n4);        n2.setRightChild(n5);        n3.setRightChild(n6);        System.out.println(CountTheDeepness.countDeepness(n1));    }}

运行结果:

迭代

思路:

  • 判断根节点是否为空

  • 定义三个变量,分别为层数,当前层的节点数,下一层的节点数

  • 当队列不为空时,得到当前节点,把当前层节点数-1,判断当前节点有无左右节点,有的话放到队列里,并且修改下一层节点数

  • 当当前层节点数为0时,把深度+1,把当前层移到下一层

public static int countDeepnessByIteration(BinaryTree root) {        // 判断根节点是否为空        if (root == null)            // 为空返回0            return 0;        // 定义三个变量,分别为层数,当前层的节点数,下一层的节点数        int depth = 0, currentLevelNodes = 1, nextLevelNodes = 0;        // 使用队列来实现        Queue<BinaryTree> binaryTrees = new LinkedList<BinaryTree>();        binaryTrees.add(root);        // 当队列不为空时        while (!binaryTrees.isEmpty()) {            // 得到当前节点            BinaryTree currentNode = binaryTrees.remove();            // 把当前层节点数-1            currentLevelNodes--;            // 判断当前节点有无左右节点            if (currentNode.getLeftChild() != null) {                // 有的话放到队列里,并且修改下一层节点数                binaryTrees.add(currentNode.getLeftChild());                nextLevelNodes++;            }            if (currentNode.getRightChild() != null) {                binaryTrees.add(currentNode.getRightChild());                nextLevelNodes++;            }            // 当当前层节点数为0时            if (currentLevelNodes == 0) {                // 把深度+1                depth++;                // 把当前层移到下一层                currentLevelNodes = nextLevelNodes;                nextLevelNodes = 0;            }        }        return depth;    }

测试代码:

package com.xinpaninjava.btree;public class BinaryTreeCountNodesTest {    public static void main(String[] args) {        BinaryTree n1 = new BinaryTree(1);        BinaryTree n2 = new BinaryTree(2);        BinaryTree n3 = new BinaryTree(3);        BinaryTree n4 = new BinaryTree(4);        BinaryTree n5 = new BinaryTree(5);        BinaryTree n6 = new BinaryTree(6);        n1.setLeftChild(n2);        n1.setRightChild(n3);        n2.setLeftChild(n4);        n2.setRightChild(n5);        n3.setRightChild(n6);        System.out.println("iteration:"+CountTheDeepness.countDeepnessByIteration(n1));    }}

运行结果:

【全文完】