首先,来了解下3中遍历方式的区别:
【前序遍历】按照 根、左、右 的次序进行遍历
【中序遍历】按照 左、根、右 的次序进行遍历
【后序遍历】按照 左、右、根 的次序进行遍历
树节点的结构
/** * 单个树节点的结构 * @param {number} val * @param {TreeNode} left * @param {TreeNode} right */ function TreeNode(val = 0, left = null, right = null) { this.val = val; this.left = left; this.right = right; }
然后,我们再来熟悉一下二叉树这3种遍历的递归实现
1. 前序遍历
/** * @param {TreeNode} root * @return {number[]} */ var preorderTraversal = function(root) { if (root === null) return []; // 按前序的次序来存储节点的值 const ans = []; /** * 递归遍历树节点 */ const traversal = (node) => { // 如果该子节点不存在,则终止递归 if (node === null) return; // 处理当前节点 ans.push(node.val); // 处理当前节点的左子树 traversal(node.left); // 处理当前节点的右子树 traversal(node.right); }; traversal(root); return ans; };
2. 中序遍历
// 思路同上,只需将部分代码调整如下 // ... // 处理当前节点的左子树 traversal(node.left); // 处理当前节点 ans.push(node.val); // 处理当前节点的右子树 traversal(node.right); // ...
3. 后序遍历
// 思路同上,只需将部分代码调整如下 // ... // 处理当前节点的左子树 traversal(node.left); // 处理当前节点的右子树 traversal(node.right); // 处理当前节点 ans.push(node.val); // ...
遍历版本
前序
// 二叉树的前序遍历 var preorderTraversal = function(root) { if (root === null) return []; // 使用栈保存尚未读取值的树节点 const stk = [root]; // 保存遍历过后的节点值 const ans = []; while (stk.length > 0) { // 推出栈顶节点,访问其值并处理其左右子节点 const node = stk.pop(); ans.push(node.val); if (node.right !== null) stk.push(node.right); if (node.left !== null) stk.push(node.left); } return ans; };
中序
// 二叉树的中序遍历 var inorderTraversal = function(root) { if (root === null) return []; // 存放节点值 const ans = []; // 存放未访问过的节点 const stk = []; // 节点指针 let cur = root; // 按照左 中 右遍历节点 while (cur !== null || stk.length > 0) { // 先将当前轮次可以遍历到的左子节点推入栈 while (cur !== null) { stk.push(cur); cur = cur.left; } // 取出栈顶节点 const node = stk.pop(); ans.push(node.val); // 如果存在右子节点,则相应地对其进行遍历 if (node.right !== null) cur = node.right; } return ans; };
后序
// 后序遍历 var postorderTraversal = function(root) { if (root === null) return []; // 后序遍历次序是左右根 // 前序遍历次序是根左右(尝试将其变化为 根右左 后进行反转) const stk = [root]; const ans = []; while (stk.length > 0) { const node = stk.pop(); ans.push(node.val) if (node.left !== null) stk.push(node.left); if (node.right !== null) stk.push(node.right); } return ans.reverse(); };
End