题目描述
利用栈实现二叉树的非递归先序、中序、后序遍历
为什么使用栈呢?
因为一个二叉树只有从上到下的路径,没有回去的路径
于是要想一个结构,让这个路径能从下到上往回走
那么栈就很适合这样的问题
为什么一个递归版本改非递归版本这么难改?
原因是你不能把所有的东西都压栈,自己做栈的话只能放一个结点类型,
很多信息会丢掉,这就是难改的原因
1. 非递归先序遍历
二叉树根结点先进栈,如果栈不为空则弹出栈顶并打印
然后先压右再压左,如此遍历就是中->左->右
2. 非递归中序遍历
如果当前结点为空,从栈拿一个打印,然后往右走
如果当前结点不空,当前结点进栈,然后往左走,一压压一溜
3. 非递归后序遍历
根据前序遍历的非递归写法,我们知道
要想实现前序遍历:中 -> 左 -> 右
顺序的遍历,可以先压右再压左
现要实现后序遍历:左 -> 右 -> 中
顺序的遍历,
我们不妨先实现 中 -> 右 -> 左
顺序的这样一个后序遍历的逆序,
那么根据前序遍历,我们可以先压左再压右,来实现这个 中 -> 右 -> 左
顺序
在打印的时候,我们不打印,而是添加到栈中。
又因为栈依次弹出栈顶可以实现某种顺序的逆序,这样,我们就实现了左 -> 右 -> 中
顺序
测试结果及代码
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
void pre(TreeNode *head) {
if (head == NULL)
return;
stack<TreeNode*> stk;
stk.push(head);
while (!stk.empty()) {
head = stk.top();
cout << head->val << " ";
stk.pop();
if (head->right != NULL)
stk.push(head->right);
if (head->left != NULL)
stk.push(head->left);
}
}
void in(TreeNode *head) {
if (head != NULL) {
stack<TreeNode*> stk;
while (!stk.empty() || head != NULL) {
if (head != NULL) {
stk.push(head);
head = head->left; // 当前结点会把自己的左边全部压栈
}
else {
head = stk.top();
stk.pop();
cout << head->val << " ";
head = head->right;
}
}
}
}
void pos(TreeNode *head) {
if (head != NULL) {
stack<TreeNode*> stk1;
stack<TreeNode*> stk2;
stk1.push(head);
while (!stk1.empty()) {
head = stk1.top();
stk1.pop();
stk2.push(head);
if (head->left != NULL)
stk1.push(head->left);
if (head->right != NULL)
stk1.push(head->right);
}
while (!stk2.empty()){
cout << stk2.top()->val << " ";
stk2.pop();
}
}
}
void preOrder(TreeNode *head) {
if (head != NULL) {
cout << head->val << " ";
preOrder(head->left);
preOrder(head->right);
}
}
void inOrder(TreeNode *head) {
if (head != NULL) {
inOrder(head->left);
cout << head->val << " ";
inOrder(head->right);
}
}
void posOrder(TreeNode *head) {
if (head != NULL) {
posOrder(head->left);
posOrder(head->right);
cout << head->val << " ";
}
}
};
int main(int argc, char* argv[]){
TreeNode *head = new TreeNode(3);
head->left = new TreeNode(2);
head->left->left = new TreeNode(1);
head->right = new TreeNode(4);
head->right->left = new TreeNode(5);
head->right->right = new TreeNode(6);
Solution s;
cout << "递归前序遍历 :";
s.preOrder(head);
cout << endl;
cout << "非递归前序遍历:";
s.pre(head);
cout << endl;
cout << "递归中序遍历 :";
s.inOrder(head);
cout << endl;
cout << "非递归中序遍历:";
s.in(head);
cout << endl;
cout << "递归后序遍历 :";
s.posOrder(head);
cout << endl;
cout << "非递归后序遍历:";
s.pos(head);
cout << endl;
return 0;
}```