前几天面试时被问到,之前一直用递归写法也没想过优化,这次被问到了就搞搞。
前中序遍历思路很简单,比较难的是后序。后序有两点要考虑到:
1.当前结点是入栈过左子结点。
2.当前结点是否左右子结点都处理完了。
#include <bits/stdc++.h>
using namespace std;
typedef struct Node* node;
struct Node{//树结点
int value;
node left;
node right;
};
node createNode(int _value = 0){
node p = new Node();
p->value = _value;
p->left = p->right = NULL;
return p;
}
void InorderTraversal(node root){
if(root == NULL)return;
stack<node> st;
node p = root;
while(!st.empty() || p){
if(p){
st.push(p);
p = p->left;
}
else{
p = st.top();
st.pop();
cout << p->value << endl;
p = p->right;
}
}
}
void PreorderTraversal(node root){
if(root == NULL)return;
stack<node> st;
node p = root;
while(!st.empty() || p){
if(p){
cout << p->value << endl;
st.push(p);
p = p->left;
}
else{
p = st.top();
st.pop();
p = p->right;
}
}
}
void PostorderTraversal(node root){
if(root == NULL)return;
stack<node> st;
node p = root;
bool flag = true;
//标记当前结点是否入栈过左子结点
while(!st.empty() || p){
if(flag && p){
st.push(p);
p = p->left;
}
else{
if(p == st.top()->right){//如果当前结点是栈顶结点得右结点那么直接输出栈顶结点
p = st.top();
st.pop();
cout << p->value << endl;
flag = false;
continue;
}
p = st.top();
if(p->right){
p = p->right;
flag = true;
}
else{
st.pop();
cout << p->value << endl;
flag = false;
}
}
}
}
node add(node root,int _value){//结点插入函数
if(root == NULL){
root = createNode(_value);
return root;
}
node p = root;
while(p){
if(p->value < _value){
if(p->right)p = p->right;
else {
p->right = createNode(_value);
break;
}
}
else{
if(p->left)p = p->left;
else {
p->left = createNode(_value);
break;
}
}
}
return root;
}
int main(){
node root = NULL;
int a;
while(cin >> a){
root = add(root,a);
}
PreorderTraversal(root);
cout << endl;
InorderTraversal(root);
cout << endl;
PostorderTraversal(root);
return 0;
}