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));
}
}
运行结果:
【全文完】