#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
struct ListNode {
int val;
ListNode *left, *right;
ListNode() = default;
ListNode(int val, ListNode* left, ListNode* right) {
this -> val = val;
this -> left = left;
this -> right = right;
}
};
ListNode* build (vector<int> &a, int x, int sz) {
ListNode *head = new ListNode(a[x], nullptr, nullptr);
// int lx = x << 1, rx = x << 1 | 1; // start_pos = 1
int lx = (x << 1) + 1, rx = (x << 1) + 2; // start_pos = 0;
if (lx <= sz) {
head -> left = build(a, lx, sz);
}
if (rx <= sz) {
head -> right = build(a, rx, sz);
}
return head;
}
void preOrder (ListNode* now, vector<int> &res) {
res.push_back(now -> val);
if (now -> left != nullptr) preOrder(now -> left, res);
if (now -> right != nullptr) preOrder(now -> right, res);
}
void preNoRecur (ListNode* head, vector<int> &res) {
stack<ListNode*> st; st.push(head);
while (!st.empty()) {
ListNode* now = st.top(); st.pop();
res.push_back(now -> val);
if (now -> right != nullptr) st.push(now -> right);
if (now -> left != nullptr) st.push(now -> left);
}
}
void pre2 (ListNode* head, vector<int> &res) {
stack<ListNode*> st;
ListNode* now = head;
while (now != nullptr || !st.empty()) {
while (now != nullptr) {
st.push(now);
res.push_back(now->val);
now = now -> left;
}
if (!st.empty()) {
now = st.top(); st.pop();
now = now -> right;
}
}
}
void inOrder (ListNode* now, vector<int> &res) {
if (now -> left != nullptr) inOrder(now -> left, res);
res.push_back(now -> val);
if (now -> right != nullptr) inOrder(now -> right, res);
}
void inNoRecur1 (ListNode* head, vector<int> &res) {
stack<ListNode*> st;
ListNode* now = head;
while (now != nullptr || !st.empty()) {
while (now != nullptr) {
st.push(now);
now = now -> left;
}
if (!st.empty()) {
now = st.top(); st.pop();
res.push_back(now -> val);
now = now -> right;
}
}
}
void inNoRecur2 (ListNode* head, vector<int> &res) {
if (head == nullptr) return;
stack<pair<ListNode*, int> > st; st.push({head, 0});
while (!st.empty()) {
ListNode* now = st.top().first;
if (st.top().second == 0) {
++ st.top().second;
if (now -> left != nullptr) st.push({now -> left, 0});
} else {
st.pop();
res.push_back(now -> val);
if (now -> right != nullptr) st.push({now -> right, 0});
}
}
}
void postOrder (ListNode* now, vector<int> &res) {
if (now -> left != nullptr) postOrder(now -> left, res);
if (now -> right != nullptr) postOrder(now -> right, res);
res.push_back(now -> val);
}
void postNoRecur (ListNode* head, vector<int> &res) {
if (head == nullptr) return;
stack<pair<ListNode*, int> > st; st.push({head, 0});
while (!st.empty()) {
ListNode* now = st.top().first;
if (st.top().second == 0) {
++ st.top().second;
if (now -> right != nullptr) st.push({now -> right, 0});
if (now -> left != nullptr) st.push({now -> left, 0});
} else {
res.push_back(now -> val);
st.pop();
}
}
}
void print(vector<int> &ans) {
for (int x: ans) cout << x << " ";
cout << endl;
ans.clear();
}
int main()
{
vector<int> a = {1,2,3,4,5,6,7,8,9};
ListNode *rt = build(a, 0, 8); // start_pos = 0;
// ListNode *rt = build(a, 1, 9); // start_pos = 1;
vector<int> ans;
preOrder (rt, ans);
printf("preOrder: "); print(ans);
preNoRecur (rt, ans);
printf("preNoRecur1:"); print(ans);
pre2 (rt, ans);
printf("preNoRecur2:"); print(ans);
puts("");
inOrder (rt, ans);
printf("inOrder : "); print(ans);
inNoRecur1 (rt, ans);
printf("inNoRecur1: "); print(ans);
inNoRecur2 (rt, ans);
printf("inNoRecur2: "); print(ans);
puts("");
postOrder (rt, ans);
printf("postOrder: "); print(ans);
postNoRecur (rt, ans);
printf("postNoRecur:"); print(ans);
return 0;
}