二叉树遍历(先序,中序,后续)(递归,栈,mirros)

#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;


}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值