DFS(Deep First Search)深度优先搜寻 与 BFS(Breath First Search)广度优先搜寻
DFS:用到了栈构造,先进后出,重点在于递归,适合寻找特定指标
BFS:用到了队列构造,先进先出,重点在于队列,适合大范畴搜查
二叉树的深度优先
二叉树的前序遍历
二叉树的中序遍历
二叉树的后序遍历
(上面解法以中序遍历为例)
1. 递归
工夫复杂度:O(n)
空间复杂度:O(n)
先判断根节点是否存在,再遍历左节点,最初遍历右节点
var inorderTraversal = function(root) { const res = []; const inorder = (root) => { if (!root) { return; } inorder(root.left); res.push(root.val); inorder(root.right); } inorder(root); return res;};
2. 迭代
工夫复杂度:O(n)
空间复杂度:O(n)
与办法1相似,区别在于递归时隐式保护一个栈,而在迭代时须要显式地将这个栈模仿进去,其余的实现与细节都雷同
var inorderTraversal = function(root) { const res = []; const stk = []; while (root || stk.length) { while (root) { stk.push(root); root = root.left; } root = stk.pop(); res.push(root.val); root = root.right; } return res;};
3. Morris 遍历
工夫复杂度:O(n)
空间复杂度:O(1)
- 如果没有左节点,先将值退出答案数组,再拜访右节点,即 x = x.right
- 如果有左节点,则找到左节点上最右的节点(即左子树中序遍历的最初一个节点,在中序遍历中的前驱节点),记为 predecessor 。依据 predecessor 的右节点是否为空,进行如下操作:
- 如果 \textit{predecessor}predecessor 的右节点为空,则将其右节点指向x,而后拜访左节点,即 x = x.left
- 如果 predecessor 的右节点不为空,则此时其右节点指向 x,阐明曾经遍历完左子树,咱们将 predecessor 的右节点置空,将 x 的值退出答案数组,而后拜访 x 的右节点,即 x = x.right
- 反复上述操作,直至拜访完整棵树
var inorderTraversal = function(root) { const res = []; let predecessor = null; while (root) { if (root.left) { // predecessor 节点就是以后 root 节点向左走一步,而后始终向右走至无奈走为止 predecessor = root.left; while (predecessor.right && predecessor.right !== root) { predecessor = predecessor.right; } // 让 predecessor 的右指针指向 root,持续遍历左子树 if (!predecessor.right) { predecessor.right = root; root = root.left; } // 阐明左子树曾经拜访完了,咱们须要断开链接 else { res.push(root.val); predecessor.right = null; root = root.right; } } // 如果没有左孩子,则间接拜访右孩子 else { res.push(root.val); root = root.right; } } return res;};
二叉树的广度遍历
二叉树的层序遍历
工夫复杂度:O(n)
空间复杂度:O(n)
var levelOrder = function(root) { const ret = []; if (!root) { return ret; } const q = []; q.push(root); while (q.length !== 0) { const currentLevelSize = q.length; ret.push([]); for (let i = 1; i <= currentLevelSize; ++i) { const node = q.shift(); ret[ret.length - 1].push(node.val); if (node.left) q.push(node.left); if (node.right) q.push(node.right); } } return ret;};