//! 前序遍历的非递归版本,精髓在于用栈模拟递归的过程,但实际进栈出栈顺序与递归并不一样,
//! 比较抽象,建议画图理解,比较重要
void BinarySearchTreesZH::preorderTraversalNoRecursion(Node *node)
{
stack<Node *> stk;
if (node == nullptr)
{
return;
}
stk.push(node);
while (stk.size() != 0)
{
Node *top = stk.top();
cout << stk.top()->element << " ";
stk.pop();
//! 注意前序遍历是中左右,出栈顺序是先左后右,进栈就要先右后左
if (top->right != nullptr)
{
stk.push(top->right);
}
if (top->left != nullptr)
{
stk.push(top->left);
}
}
}
//! 中序遍历,非递归版,跟上一个前序遍历的非递归版比,思路相同,但是实现方法和过程完全不同
//! 比较抽象,依然建议画图理解
//! 巧妙地改变了入栈顺序实现了中序遍历
void BinarySearchTreesZH::inorderTraversalNoRecursion(Node *node)
{
if (node == nullptr)
{
return;
}
stack<Node *> stk;
stk.push(node);
while (stk.size() != 0)
{
while (node->left != nullptr)
{
stk.push(node->left);
node = node->left;
}
//! 整体思路为遇到根节点,就遍历左子树的所有左节点,并全部入栈,然后挨个出栈,
//! 出栈中检测是否有右节点,如果有则以右节点为根结点,再次遍历全部左结点,全部入栈,然后挨个出栈
Node *top = stk.top();
cout << top->element << " ";
stk.pop();
if (top->right != nullptr)
{
node = top->right;
stk.push(top->right);
}
}
}
//! 后序遍历,非递归版,可以通过改变前序遍历非递归版中左右结点的入栈顺序,和翻转数组的想法实现
void BinarySearchTreesZH::postorderTraversalNoRecursion(Node *node)
{
if (node == nullptr)
{
return;
}
string s = " ";
stack<Node *> stk;
stk.push(node);
Node *top = stk.top();
while (stk.size() != 0)
{
top = stk.top();
stk.pop();
s = s + to_string(top->element) + " ";
if (top->left != nullptr)
{ //! 整体思路和前序遍历相同,入栈顺序自己想想前序中左右,和后序左右中,就明白了
stk.push(top->left);
}
if (top->right != nullptr)
{
stk.push(top->right);
}
}
reverse(s.begin(), s.end()); //reverse函数反转字符串
cout << s;
}