一般的递归其实就够用了,手动模拟一个栈更方便自己的理解
如下图所示,对二叉树进行前序遍历,打印了根节点,再遍历根节点的左节点,这样就递归调用
了preOrder 的函数,函数调用的时候,系统会帮你压栈,但是如果压栈次数过多,就会爆栈。大佬都喜欢
玩手工栈。
我们看 LeetCode 144题
过程很简单,递归解法是不停地压栈,当栈都压完了,就会返回到上
一层函数的调用,如上图的绿色箭头所示
先序遍历无非是 根,左,右
手工压栈 :右,左,根 ,弹栈顺序:根,左,右
这样就非常完美的解释了压栈的过程
下面是两种代码实现:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Command {
String cmd;
TreeNode node;
public Command(String cmd,TreeNode node) {
this.cmd = cmd;
this.node = node;
}
}
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> ans = new ArrayList();
if(root==null) return ans;
ArrayList<Command> stack = new ArrayList();
stack.add(new Command("push",root));
while(!stack.isEmpty())
{
Command curCmd = stack.remove(stack.size()-1);
if(curCmd.cmd.equals("add")) {
ans.add(curCmd.node.val);
}else{
if(curCmd.node.right!=null) {
stack.add(new Command("Push",curCmd.node.right));
}
if(curCmd.node.left!=null) {
stack.add(new Command("push",curCmd.node.left));
}
stack.add(new Command("add",curCmd.node));
}
}
return ans;
}
}
方法二:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };stack--> right->left->center
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> res;
if(root==NULL){
return res;
}
stack<TreeNode*> bucket;
bucket.push(root);
while(!bucket.empty()) {
TreeNode* begin = bucket.top();
bucket.pop();
if(begin->right) {
bucket.push(begin->right);
}
if(begin->left) {
bucket.push(begin->left);
}
res.push_back(begin->val);
}
return res;
}
};