dfs
dfs指的是深度优先遍历,通常在树或者图的拓扑结构中使用,算法思想是每次遍历到一个节点时,会根据这个方向继续遍历该节点的子节点,深挖下去,直到下面挖的节点没有子节点时,再回到该上一个节点。
dfs一般使用递归来实现,因为递归完美符合dfs的思想。如果不使用递归的话,就是用栈来实现其思想,因为本质上递归也是栈的一种应用。每次遍历节点时把节点压到栈中,然后继续把子节点压到栈中,直到没有子节点了就出栈。
前中后序遍历
1
/ \
2 3
/ \ \
4 5 6
- 层次遍历顺序:[1 2 3 4 5 6]
- 前序遍历顺序:[1 2 4 5 3 6]
- 中序遍历顺序:[4 2 5 1 3 6]
- 后序遍历顺序:[4 5 2 6 3 1]
层次遍历使用 BFS 实现,利用的就是 BFS 一层一层遍历的特性;而前序、中序、后序遍历利用了 DFS 实现。
前序、中序、后序遍只是在对节点访问的顺序有一点不同,其它都相同。
- 前序
//递归
void dfs(TreeNode root) {
visit(root);
dfs(root.left);
dfs(root.right);
}
//非递归
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.empty()){
TreeNode node = stack.pop();
if(node==null) continue;
ret.add(node.val);
stack.push(node.right);
stack.push(node.left);
}
return ret;
}
}
- 中序
//递归
void dfs(TreeNode root) {
dfs(root.left);
visit(root);
dfs(root.right);
}
//非递归
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
if(root==null) return ret;
Stack<TreeNode> stack = new Stack<>();
while(root!=null || !stack.empty()){
while(root!=null){
stack.push(root);
root = root.left;
}
TreeNode node = stack.pop();
ret.add(node.val);
root = node.right;
}
return ret;
}
}
- 后序
//递归
void dfs(TreeNode root) {
dfs(root.left);
dfs(root.right);
visit(root);
}
//非递归
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.empty()){
TreeNode node = stack.pop();
if(node==null) continue;
ret.add(node.val);
stack.push(node.left);
stack.push(node.right);
}
Collections.reverse(ret);
return ret;
}
}
bfs
bfs指的是广度优先遍历,通常也在树或者图的拓扑结构中使用,算法思想是每次遍历到一个节点时,会继续遍历跟该节点同一层的节点,直到同一层的节点都被遍历完了,才开始往该节点的子节点遍历。
bfs一般通过队列来实现,每次将节点插入对尾,访问一个节点时从队头出来,然后把该节点的子节点都插入对尾。
二叉树的层平均值
链接:二叉树的层平均值
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
List<Double> ret = new ArrayList<>();
while(queue.size()!=0){
int num = queue.size();
Double sum = 0.0;
for(int i = 0; i<num; i++){
TreeNode node = queue.poll();
sum += (double)node.val;
if(node.left!=null) queue.offer(node.left);
if(node.right!=null) queue.offer(node.right);
}
ret.add(sum/num);
}
return ret;
}
}
参考:https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3%20-%20%E6%A0%91.md