LeetCode94,144,145. 二叉树前序中序后序--递归和非递归实现

LeetCode94,144,145. 二叉树前序中序后序--递归和非递归实现

code

// Definition for a binary tree node.
// 先序遍历-递归版本
// struct TreeNode
// {
// 	int val;
// 	TreeNode *left;
// 	TreeNode *right;
// 	TreeNode(int x): val(x),left(NULL),right(NULL) {}
// };
class Solution {
public:
	// 这里的返回值是void,可以在函数体内输出值
	vector<int> res;
	vector<int> preorderTraversal(TreeNode* root) {
		if (root!=NULL) {
			res.push_back(root->val);
			preorderTraversal(root->left);
			preorderTraversal(root->right);
		}		
		return res;
	}	
}
// 先序遍历-迭代版本-使用stack栈来辅助运算
// 1. 把根节点push到stack中
// 2. 循环检查stack是否为空,如果不为空,则取出栈顶元素,保存该值,然后看右节点是否存在,
//	  如果存在就push到栈中(因为先进后出,所以先push右节点)
// 3. 再看其左节点是否存在,存在就push到栈中。
class Solution {
public:
	vector<int> res;  //这里要定义在外面,不然每次递归都会重新赋值
    vector<int> preorderTraversal(TreeNode* root) {
        if(!root) return{};  //函数返回vector向量,所以需要加大括号
        stack<TreeNode*> s{ {root} }; //先存根节点
        while( !s.empty()) {   //栈不空,取出栈顶元素
            TreeNode* t = s.top(); 
			s.pop();
            res.push_back(t->val);
            if(t->right) s.push(t->right);
            if(t->left) s.push(t->left);
        }
        return res;
    }
};

// 中序遍历 递归版本
class Solution {
public:
    vector<int> res;
    vector<int> inorderTraversal(TreeNode* root) {
        if(root!=NULL) {
            //cout<<"test"<<endl;
            inorderTraversal(root->left);
            res.push_back(root->val);
            inorderTraversal(root->right);
        }
        return res;
    }
};

// 中序遍历,非递归版本,同样借助栈stack
class Solution {
public:
	vector<int> inorderTraversal(TreeNode* root) {
		vector<int> res;
		stack<TreeNode*> s;
		TreeNode* p = root;
		while ( p || ! s.empty() )
		{
			while (p)
			{
				s.push(p);
				p = p->left;
			}
			p = s.top();
			s.pop();
			res.push_back(p->val);
			p = p->right;
		}
		return res;
	}
};

// 后序遍历--递归版本
// 左->右->根
class Solution {
public:
	vector<int> res;
	vector<int> postorderTraversal(TreeNode* root) {
		if(root!=NULL) {
			postorderTraversal(root->left);
			postorderTraversal(root->right);
			res.push_back(root->val);
		}
		return res;
	}
}
// 后序遍历--非递归版本,同样利用栈stack结构(核心思想:利用改变先序遍历的方式)
// 后续遍历是左->右->根,所以当一个节点被pop出来,要么是没有子节点,要么左右子节点已经被遍历。
// 我们知道先序和后序无法唯一确定一棵二叉树。
// 而这里我们需要通过先序遍历来求后序遍历,我们知道先序遍历是 根->左->右。
// 而由于栈是后进先出,所以我们压栈的顺序应该是 根->右->左
// 故只需要将先序遍历的左右调换并把访问方式打印改为压入另一个栈

// 这里采用的是双栈的方法
class Solution {
public:
	vector<int> postorderTraversal(TreeNode* root) {
		if (!root) return {};
		vector<int> res;
		stack<TreeNode*> s1,s2;
		s1.push(root);
		while (!s1.empty())
		{
			TreeNode *t = s1.top();
			s1.pop();
			//这里是存入节点,而不是它的值(可以通过输出后续遍历的结果,来判断这句代码插入什么地方)
			s2.push(t);  
			if(t->left) s1.push(t->left);
			if(t->right) s1.push(t->right);
		}
		while(!s2.empty())
		{
			res.push_back(s2.top()->val);   //返回结果存入的是值,而不是节点
			s2.pop();
		}
		return res;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值