时隔一年多,对二叉树的了解也就停留了一年前的水平,后序遍历的非递归写法还是很有意思的,模拟了栈的运行。值得注意的一些细节
- 树为空树的处理
- 对递归栈的深入了解至关重要
- 非递归写法模拟了递归写法的栈(方便后序讲解)
非常仓促的拍了一个比较仓促的并且比较丑的代码, RE了一发QAQ..。
注:以下代码值得信任,A过题了已经
#include <bits/stdc++.h>
using namespace std;
#define met(a, b) memset(a, b, sizeof(a));
const int maxn = 100000;
struct TREENODE {
TREENODE(char c):data(c){};
char data;
TREENODE *lchild, *rchild;
};
int pos = 0;
char ans[maxn], ans1[maxn];
int top = 0, top1 = 0;;
TREENODE * insert(TREENODE * root, char _data[]);
void postOrderTravel1(TREENODE * root);
void postOrderTravel2(TREENODE * root);
void inOrder(TREENODE * root);
int main() {
char s[maxn];
while(~scanf("%s", s)) {
top = top1 = 0;
pos = 0;
int len = strlen(s);
TREENODE * root = insert(root, s);
postOrderTravel2(root);
inOrder(root);
for(int i = 0; i < top1; i++) {
printf("%c", ans1[i]);
}
puts("");
for(int i = 0; i < top; i++) {
printf("%c", ans[i]);
//if(i != top - 1) printf(" ");
}
puts("");
}
return 0;
}
TREENODE * insert(TREENODE * root, char _data[]) {
if(_data[pos++] == ',') {
root = NULL;
return root;
}
root = new TREENODE(_data[pos - 1]);
root -> lchild = insert(root -> lchild, _data);
root -> rchild = insert(root -> rchild, _data);
return root;
};
void postOrderTravel1(TREENODE * root) {
if(!root) return;
postOrderTravel1(root -> lchild);
postOrderTravel1(root -> rchild);
ans[top++] = root -> data;
}
void postOrderTravel2(TREENODE * root) {
stack<TREENODE *> s;
TREENODE *pre = NULL;
while(!s.empty()) s.pop();
if(root) // if root is NULL will RunTimeError
s.push(root);
while(!s.empty()) {
TREENODE * now = s.top();
bool f = (pre != NULL) && (now -> lchild == pre || now -> rchild == pre);
if((now -> lchild == NULL && now -> rchild == NULL) || f) {
ans[top++] = now -> data;
s.pop();
pre = now;
continue;
}
if(now -> rchild) {
s.push(now -> rchild);
}
if(now -> lchild) {
s.push(now -> lchild);
}
}
}
void inOrder(TREENODE * root) {
if(!root) return;
inOrder(root -> lchild);
ans1[top1++] = root -> data;
inOrder(root -> rchild);
}