# 二叉树的前序遍历
# 题目
给定一个二叉树,返回它的 前序
遍历。
# 示例
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,2,3]
请分别以 递归
、非递归
方法实现?
# 代码
# Johninch
本部分是三序遍历的实现,主要分为两类:递归和迭代。
三序遍历的递归方式非常简单,而对应的迭代法,本质上是在模拟递归,因为在递归的过程中使用了系统栈,所以在迭代的解法中常用Stack来模拟系统栈。
其实三序遍历都有一种莫里斯遍历解法,但这种方法会破坏原树结构,且不易理解,感兴趣的话去leetcode研究下。
# 前序遍历 - 递归
const preorder = (root, arr = []) => {
if (root) {
arr.push(root.val)
preorder(root.left, arr)
preorder(root.right, arr)
}
return arr
}
# 前序遍历 - 迭代 - 栈遍历 (前序入栈就输出)
- 每拿到一个 节点 就把它 压栈;
- 继续对这个节点的 左子树 重复 过程1,直到左子树为 空;
- 因为保存在 栈 中的节点都遍历了 左子树 但是没有遍历 右子树,所以对栈中节点 [出栈] 并对它的 右子树 重复 过程1
- 直到遍历完所有节点
const preorderTraversal = (root) => {
const res = [];
const stack = [];
let current = root;
while (current || stack.length > 0) {
while (current) {
res.push(current.val); // 前序入栈就输出,中序出栈再输出,后续是对前序的修改
stack.push(current);
current = current.left;
}
current = stack.pop();
current = current.right;
}
return res;
};
# niannings
/**
* 前序遍历算法:
* 1. 初始化一个栈stack,并将根节点压入;
* 2. 从stack中弹出一个node,**访问**它,并将node的右、左子节点依次压入stack(如果有的话);
* 3. 重复步骤2,直到stack清空;
* @param handler 处理函数
*/
export function frontEach<N extends IBinaryTreeNodeBase = IBinaryTreeNodeBase>(
root: N,
handler: (node: N) => void
) {
if (root === null) return;
const stack = [root];
while (stack.length) {
const node = stack.pop();
handler(node);
if (node.right) {
stack.push(node.right as N);
}
if (node.left) {
stack.push(node.left as N);
}
}
}
# febcat
preorderTraversal(node = this.root) {
let preorderTraversalArr = [];
const loop = (node) => {
if (!node) {
return;
}
preorderTraversalArr.push(node.data);
loop(node.left);
loop(node.right);
}
loop(node);
console.log("前序排列:", preorderTraversalArr);
return preorderTraversalArr;
}
preorderTraversal2(node = this.root) {
if (!node) {
return;
}
let stack = [];
let proorderTraversalArr = [];
while (stack.length || node) {
if (node) {
stack.push(node);
proorderTraversalArr.push(node.data);
node = node.left;
} else {
node = stack.pop();
node = node.right;
}
}
console.log("前序遍历迭代:", proorderTraversalArr);
return proorderTraversalArr;
}