LeetCode Binary Tree Postorder Traversal 二叉树后序遍历 递归和非递归解法

Given a binary tree, return the postorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1
    \
     2
    /
   3

return [3,2,1].

Note: Recursive solution is trivial, could you do it iteratively?

今天又犯了个大错误,乍看这道题又轻视它了,以为不用递归也是很简单的事情。事实上,不使用递归增加了几个级数的难度啊。

不使用额外空间,我现在还是觉得不可能做到的,或许会有某些天才以后做出来吧,应该是两个思路吧:

1. 最简单应该是使用两个栈作为额外空间。感觉好浪费哦。哎呀,又感觉自己怎么那么小气啊,一点空间都不舍得,呵呵。

2. 使用额外标识,可以知道是发生了递归了,还是新进入一个node。这个好像跟回溯法差不多,但是想想还是有很大区别的。

到处上网逛了逛,好像网上的也都是这两个思路。

还是使用两个栈比较简单,下面就用递归和用两个栈实现以下吧:

 

非常简单的递归:

void postRecurse(TreeNode *node,vector<int> &onePath)
	{
		if(node == nullptr) return;
		postRecurse(node->left, onePath);
		postRecurse(node->right, onePath);
		onePath.push_back(node->val);
	}

 

非简单的非递归:

vector<int> postorderTraversal(TreeNode *root) {
		vector<int> postPath; 
		postPath = postIter(root);
		reverse(postPath.begin(), postPath.end());
		return postPath;
	}
vector<int> postIter(TreeNode *node) 
	{
		vector<int> output;
		if (!node) return output;
		vector<TreeNode *> vt;
		vt.push_back(node);
		while (!vt.empty()) 
		{
			TreeNode *cur = vt.back();
			output.push_back(cur->val);
			vt.pop_back();
			if (cur->left)
				vt.push_back(cur->left);
			if (cur->right)
				vt.push_back(cur->right);
		}
		return output;
	}


代码优雅还是最重要的,最后代码我觉得还算优雅吧,不过也参考了一下别人的代码,改进一点自己的。

最近一直在研究算法,连我的本行图形学都有荒废了,不过不要紧吧。图形学基础打的非常好了,不会那么容易丢的。先练好算法,以便研究更深奥的图形学。

虽然感觉最近功力提升了,但是还是觉得功力不到家啊,这道题琢磨了我很长时间,要努力提升!


2014-1-10更新:

上面的非递归算法,需要对后序遍历的顺序非常熟悉,然后才能逆序访问,最后反转输出结果,虽然很适合这道题,因为题目要求保存结果,但是我们也可以正常顺序非递归访问。

程序如下:

vector<int> postorderTraversal(TreeNode *root) 
	{
		vector<int> rs;
		if (!root) return rs;

		stack<TreeNode *> stk;
		stk.push(root);

		while (!stk.empty())
		{
			while (stk.top()->left) stk.push(stk.top()->left);
			if (stk.top()->right) stk.push(stk.top()->right);
			else 
			{
				TreeNode *t = stk.top();
				stk.pop();
				rs.push_back(t->val);
				if (!stk.empty())
				{
					if (stk.top()->left == t) stk.top()->left = NULL;
					else stk.top()->right = NULL;
				}
			}
		}
		return rs;
	}
这样访问就会破坏了原树的结构,我们可以增加两个标志,就不会破坏原树结构了。

vector<int> postorderTraversal(TreeNode *root) 
	{
		vector<int> rs;
		if (!root) return rs;

		stack<TreeNode *> stk;
		stk.push(root);
		bool lflag = false;
		bool rflag = false;

		while (!stk.empty())
		{
			while (!lflag && stk.top()->left) stk.push(stk.top()->left);
			if (!rflag && stk.top()->right)
			{
				stk.push(stk.top()->right);
				lflag = false;
			}
			else 
			{
				TreeNode *t = stk.top();
				stk.pop();
				rs.push_back(t->val);
				lflag = true;
				if (!stk.empty() && stk.top()->right == t) rflag = true;
				else rflag = false;
			}
		}
		return rs;
	}

这两个标志设计也非常巧妙的,安排不好,结果就会不正确。

非递归遍历树总结:

1 前序遍历不需要增加标志

2 中序遍历需要增加一个标志

3 后序就需要增加两个标志

难度也是一个比一个难。

//2014-2-19_1 update
	vector<int> postorderTraversal(TreeNode *root) 
	{
		vector<int> rs;
		if (!root) return rs;
		stack<TreeNode *> stk;
		stk.push(root);
		TreeNode *pre = nullptr;
		while (!stk.empty())
		{
			if ((!pre || pre->left == stk.top() || pre->right == stk.top()) 
				&& stk.top()->left)
			{
				pre = stk.top();
				stk.push(stk.top()->left);
			}
			else if (((!stk.top()->left && pre != stk.top()->right)
				|| pre == stk.top()->left) && stk.top()->right)
			{
				pre = stk.top();
				stk.push(stk.top()->right);
			}
			else
			{
				pre = stk.top();
				stk.pop();
				rs.push_back(pre->val);
			}
		}
		return rs;
	}

//2014-2-19_2 update
	vector<int> postorderTraversal(TreeNode *root) 
	{
		vector<int> rs;
		if (!root) return rs;
		stack<TreeNode *> stk;
		stk.push(root);
		while (!stk.empty())
		{
			TreeNode *t = stk.top();
			stk.pop();
			rs.push_back(t->val);
			if (t->left) stk.push(t->left);
			if (t->right) stk.push(t->right);
		}
		reverse(rs.begin(), rs.end());
		return rs;
	}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的体育馆管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本体育馆管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此体育馆管理系统利用当下成熟完善的SpringBoot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线选择试题并完成答题,在线查看考核分数。管理员管理收货地址管理、购物车管理、场地管理、场地订单管理、字典管理、赛事管理、赛事收藏管理、赛事评价管理、赛事订单管理、商品管理、商品收藏管理、商品评价管理、商品订单管理、用户管理、管理员管理等功能。体育馆管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:体育馆管理系统;SpringBoot框架;Mysql;自动化
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值