中序遍历二叉树:按照左孩子 -> 根节点 -> 右孩子的顺序遍历二叉树。
1.递归方法
void bst(TreeNode* root){
if(root == nullptr) return; //如果为空则返回
bst(root->right); //遍历左孩子
cout << root->val; //输出根节点
bst(root->left); //遍历右孩子
}
2.非递归方法
如何将递归方法转化为非递归方法?
分析中序遍历的思想可知,需要先将左子树遍历到底,那么进入了左子树而没有访问根节点和右子树的根节点当然需要存储,使得后续可以回溯访问根节点和右子树。这种条件最适合的数据结构很容易想到是栈!
递归算法是通过函数自动存储栈存储形参的地址,那么非递归算法自然需要我们自己定义一个栈,并通过循环模拟递归。
void bst(TreeNode* root){
stack<TreeNode*> s; //存储未访问根节点和右孩子的节点的栈
TreeNode* p = root;
while(p || !s.empty()){ //结束条件
while(p){ //将左子树遍历到底
s.push(p); //未访问根节点和右子树的节点入栈
p = p->left;
}
//p已到左子树最下边,开始出栈
if(!s.empty()){
p = s.top(); //回溯
s.pop();
cout << p.val;
p = p->right; //进入右子树开始新一轮遍历
}
}
}