递归转非递归一般就两种方法:
- 改变算法, 将耗空间的算法改为耗时间的算法
- 模拟递归, 使用栈模拟递归操作.
对于链式结构的二叉树遍历,显然没有办法将算法改成耗时间的,只好模拟递归。
要想模拟递归,首先要了解递归操作。递归操作本质上就是一个压栈出栈的过程,因此在模拟的时候我们需要用到一种数据结构——栈。
正文开始
1. 先序遍历
先来分析下递归算法的调用过程。
void BinaryTreePrevOrder(BTNode* root) {
if (root) {
printf("%c ", root->_data);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
}
- 开辟一个函数栈帧;
- 访问该节点;
- 开辟栈帧后先访问左孩子;
- 左孩子存在时继续步骤 1~3·····
- 当该节点不存在时,即 if(root) 非真,弹出该函数栈帧;
- 返回上一级的函数栈帧,访问右孩子,继续步骤 1.
非递归的算法思路类似,访问该节点后压栈,如果有左孩子,就访问左孩子并压栈······没有左孩子了,将上一次访问的节点弹出,并访问该节点的右孩子,然后继续下一次循环。以下代码可供参考
using std::stack;
void BinaryTreePrevOrderNonR(BTNode* root) {
stack<BTNode*> s;
BTNode* node = root;
while (!s.empty() || node) {
while