前言
转载需经过作者同意
本文承接上篇:
Java二叉树详细解析,所有基本操作及五种遍历,求深度,求大小(上)
正文
在介绍过二叉树的基本操作后,接下来我们开始分析一些在算法题中用的比较多的功能。
求二叉树的深度
要求二叉树的深度,首先会想到遍历每一条**根(root)到叶子节点(leaf)**的路径并记录其长度,然后比较哪一条路径的长度最长。这样的想法是对的,但是实现起来很麻烦。因为你需要记录每一条路径之后把所有的路径长度比较。所以这里我们还是采用另外一种方法:(递归)。
核心思想:比较两棵子树谁更长
非叶子节点有种三种情况:
1.无左子树
递归右子树+1
2.无右子树
递归左子树+1
2.左右子树均存在
那就比较左子树和右子树的长度:Math.max(递归左子树,递归右子树)+1
+1是代表当前节点本身需要被计算在内
代码如下:
public int depth()
{
if(val == null)//空节点返回0
return 0;
if(isLeaf())//子节点返回1
return 1;
//分支选择:
if(leftBTree == null)
return rightBTree.depth()+1;
else if(rightBTree == null)
return leftBTree.depth()+1;
else
return Math.max(rightBTree.depth(),leftBTree.depth())+1;
}
通过上述代码,我们将所有路径的比较转化为每个分支的两两比较。
这里的解决思路也是属于D&C的思想。
求树的大小
有了上面求深度的经验,这个问题就so easy了!
我们在上面是比较两棵子树的大小,现在不是只要把比较换成求和就可以了吗?
代码如下:
public int size()
{
if(val == null)
return 0;
if(isLeaf())
return 1;
if(leftBTree == null)
return rightBTree.size()+1;
else if(rightBTree == null)
return leftBTree.size()+1;
else
return rightBTree.size()+leftBTree.size()+1;
}
深度优先搜索(DFS)与广度优先搜索(BFS)
首先我们来了解一下**深度优先搜索(DFS)和广度优先搜索(BFS)**的遍历机制:
如图:
我们不难观察到:深度优先搜索是将一条路径遍历完后接着遍历下一条路径的,而广度优先搜索则是层序遍历。
那么在代码中我们应该如何体现出这样的机制呢?
深度优先搜索由于符合先进后出的原则,大多数情况使用栈(stack)来实现。而广度优先搜索则是符合"先进先出的原则"所以我们使用队列(queue)。
具体代码如下:
深度优先搜索:
public void DFS()
{
Stack<BinaryTree<T>> stack = new Stack<>();
stack.push(this);//root压入栈
while(!stack.isEmpty())
{
BinaryTree<T> node = null;
node = stack.pop();//出栈并读取其值
System.out.println(node.val);
if(node.rightBTree != null)stack.push(node.rightBTree);//因为是先进后出,所以先压入右子树
if(node.leftBTree != null)stack.push(node.leftBTree);
}
}
广度优先搜索:
public void BFS()
{
Deque<BinaryTree<T>> queue = new ArrayDeque<>();
queue.add(this);
BinaryTree<T> node = null;
while(!queue.isEmpty())
{
node = queue.pop();
System.out.println(node.val);
if(node.leftBTree != null)queue.add(node.leftBTree);//先进先出,所以先压入左子树
if(node.rightBTree != null)queue.add(node.rightBTree);
}
}
完整代码
由于承接上篇文章代码,测试代码功能需要参考上文。带来的不便请谅解,链接如下:
Java二叉树详细解析,所有基本操作及五种遍历,求深度,求大小(上)
public int depth()
{
if(val == null)
return 0;
if(isLeaf())
return 1;
if(leftBTree == null)
return rightBTree.depth()+1;
else if(rightBTree == null)
return leftBTree.depth()+1;
else
return Math.max(rightBTree.depth(),leftBTree.depth())+1;
}
public int size()
{
if(val == null)
return 0;
if(isLeaf())
return 1;
if(leftBTree == null)
return rightBTree.size()+1;
else if(rightBTree == null)
return leftBTree.size()+1;
else
return rightBTree.size()+leftBTree.size()+1;
}
public void DFS()
{
Stack<BinaryTree<T>> stack = new Stack<>();
stack.push(this);
BinaryTree<T> node = null;
while(!stack.isEmpty())
{
node = stack.pop();
System.out.println(node.val);
if(node.rightBTree != null)stack.push(node.rightBTree);
if(node.leftBTree != null)stack.push(node.leftBTree);
}
}
public void BFS()
{
Deque<BinaryTree<T>> queue = new ArrayDeque<>();
queue.add(this);
BinaryTree<T> node = null;
while(!queue.isEmpty())
{
node = queue.pop();
System.out.println(node.val);
if(node.leftBTree != null)queue.add(node.leftBTree);
if(node.rightBTree != null)queue.add(node.rightBTree);
}
}
尾言
不懂的小伙伴可以在评论区里面问我,一般情况24小时之内能够回复。打击一起进步!