#pragma once
#include<stack>
#include<vector>
#include<iostream>
#include <functional>
using namespace std;
class TreeNode
{
private:
// 逆转路径
static void reverse(TreeNode *from, TreeNode *to) {
TreeNode *x = from, *y = from->right, *z;
if (from == to) return;
while (x != to) {
z = y->right;
y->right = x;
x = y;
y = z;
}
};
// 访问逆转后的路径上的所有结点
static void visit_reverse(TreeNode* from, TreeNode *to,std::function< void(const TreeNode*) >& visit) {
TreeNode *p = to;
reverse(from, to);
while (true) {
visit(p);
if (p == from)
break;
p = p->right;
}
reverse(to, from);
};
public:
TreeNode();
~TreeNode(){};
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int v) :val(v), left(nullptr), right(nullptr) {};
//recursion
void preorderRecursion(TreeNode *root, vector<int> &result)
{
if (root != nullptr)
{
result.push_back(root->val);
preorderRecursion(root->left, result);
preorderRecursion(root->right, result);
}
};
void inorderRecursion(TreeNode *root, vector<int> &result)
{
if (root != nullptr)
{
inorderRecursion(root->left, result);
result.push_back(root->val);
inorderRecursion(root->right, result);
}
};
void postorderRecursion(TreeNode *root, vector<int> &result)
{
if (root != nullptr)
{
postorderRecursion(root->left, result);
postorderRecursion(root->right, result);
result.push_back(root->val);
}
};
//stack
vector<int> preorderTraversal(TreeNode *root)
{
vector<int> result;
stack<TreeNode *> stack;
stack.push(root);
while (!stack.empty()) {
TreeNode *node = stack.top();
stack.pop();
if (node->right != NULL)
stack.push(node->right);
if (node->left != NULL)
stack.push(node->left);
result.push_back(node->val);
}
return result;
};
vector<int> inorderTraversal(TreeNode *root)
{
vector<int> result;
stack<TreeNode *> stack;
stack.push(root);
while (!stack.empty()) {
while (stack.top()->left != NULL) {
stack.push(stack.top()->left);
}
while (!stack.empty()) {
TreeNode *node = stack.top();
stack.pop();
result.push_back(node->val);
if (node->right != NULL) {
stack.push(node->right);
break;
}
}
}
return result;
};
vector<int> postorderTraversal(TreeNode *root)
{
vector<int> result;
stack<TreeNode *> stack;
stack.push(root);
TreeNode *lastNode = nullptr;
while (!stack.empty()) {
while (stack.top()->left != NULL) {
stack.push(stack.top()->left);
}
while (!stack.empty()) {
if (lastNode == stack.top()->right || stack.top()->right == NULL) {
TreeNode *node = stack.top();
stack.pop();
result.push_back(node->val);
lastNode = node;
}
else if (stack.top()->right != NULL) {
stack.push(stack.top()->right);
break;
}
}
}
return result;
};
//morris
vector<int> preorderMorris(TreeNode *root) {
vector<int> result;
TreeNode *cur, *prev;
cur = root;
while (cur != nullptr) {
if (cur->left == nullptr) {
result.push_back(cur->val);
prev = cur; /* cur 刚刚被访问过 */
cur = cur->right;
}
else {
/* 查找前驱 */
TreeNode *node = cur->left;
while (node->right != nullptr && node->right != cur)
node = node->right;
if (node->right == nullptr) { /* 还没线索化,则建立线索 */
result.push_back(cur->val); /* 仅这一行的位置与中序不同 */
node->right = cur;
prev = cur; /* cur 刚刚被访问过 */
cur = cur->left;
}
else { /* 已经线索化,则删除线索 */
node->right = nullptr;
/* prev = cur; 不能有这句, cur 已经被访问 */
cur = cur->right;
}
}
}
return result;
}
vector<int> inorderMorris(TreeNode *root) {
vector<int> result;
TreeNode *cur, *prev;
cur = root;
while (cur != nullptr) {
if (cur->left == nullptr) {
result.push_back(cur->val);
prev = cur;
cur = cur->right;
}
else {
/* 查找前驱 */
TreeNode *node = cur->left;
while (node->right != nullptr && node->right != cur)
node = node->right;
if (node->right == nullptr) { /* 还没线索化,则建立线索 */
node->right = cur;
/* prev = cur; 不能有这句, cur 还没有被访问 */
cur = cur->left;
}
else { /* 已经线索化,则访问节点,并删除线索 */
result.push_back(cur->val);
node->right = nullptr;
prev = cur;
cur = cur->right;
}
}
}
return result;
}
vector<int> postorderMorris(TreeNode *root) {
vector<int> result;
TreeNode dummy(-1);
TreeNode *cur, *prev = nullptr;
std::function < void(const TreeNode*)> visit =[&result](const TreeNode *node){
result.push_back(node->val);
};
dummy.left = root;
cur = &dummy;
while (cur != nullptr) {
if (cur->left == nullptr) {
prev = cur; /* 必须要有 */
cur = cur->right;
}
else {
TreeNode *node = cur->left;
while (node->right != nullptr && node->right != cur)
node = node->right;
if (node->right == nullptr) { /* 还没线索化,则建立线索 */
node->right = cur;
prev = cur; /* 必须要有 */
cur = cur->left;
}
else { /* 已经线索化,则访问节点,并删除线索 */
visit_reverse(cur->left, prev, visit);
prev->right = nullptr;
prev = cur; /* 必须要有 */
cur = cur->right;
}
}
}
return result;
};
void cout_result(vector<int> result){
for (size_t i = 0; i < result.size(); i++)
{
cout << result[i] << " ";
}
cout << endl;
};
};
int main()
{
TreeNode *node1 = new TreeNode(1);
TreeNode *node2 = new TreeNode(2);
TreeNode *node3 = new TreeNode(3);
TreeNode *node4 = new TreeNode(4);
TreeNode *node5 = new TreeNode(5);
TreeNode *node6 = new TreeNode(6);
TreeNode *node7 = new TreeNode(7);
// 4
// / \
// 2 6
// / \ / \
// 1 3 5 7
node4->left = node2;
node4->right = node6;
node2->left = node1;
node2->right = node3;
node6->left = node5;
node6->right = node7;
//recursion
vector<int> result;
node4->preorderRecursion(node4, result);
node4->cout_result(result);//4,2,1,3,6,5,7
result.clear();
node4->inorderRecursion(node4, result);
node4->cout_result(result);//1,2,3,4,5,6,7
result.clear();
node4->postorderRecursion(node4, result);
node4->cout_result(result);//1,3,2,5,7,6,4
//stack
node4->cout_result(node4->preorderTraversal(node4));//4,2,1,3,6,5,7
node4->cout_result(node4->inorderTraversal(node4));//1,2,3,4,5,6,7
node4->cout_result(node4->postorderTraversal(node4));//1,3,2,5,7,6,4
//morris
node4->cout_result(node4->preorderMorris(node4));//4,2,1,3,6,5,7
node4->cout_result(node4->inorderMorris(node4));//1,2,3,4,5,6,7
node4->cout_result(node4->postorderMorris(node4));//1,3,2,5,7,6,4
delete node1;
delete node2;
delete node3;
delete node4;
delete node5;
delete node6;
delete node7;
return 0;
}