您的位置:首页 > 职场人生

二叉树面试题汇总(一)

2017-11-02 21:23 381 查看
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));
}

}


运行结果:



【全文完】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息