二叉树的遍历

很久没看数据结构,许多东西生疏了。这两天在leetcode上做了几道关于二叉树遍历的题目,前序和中序相对容易,但后序遍历写了好久,记录在此,以便下次回读。

题目链接:http://oj.leetcode.com/problems/binary-tree-preorder-traversal/

                    http://oj.leetcode.com/problems/binary-tree-inorder-traversal/

                    http://oj.leetcode.com/problems/binary-tree-postorder-traversal/

 关于三种遍历的代码形式很多,基本思想差不多,这里主要记录用栈来解决。

树的结构定义:

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

三种遍历:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode *root) {
		vector<int> res;
		stack<const TreeNode *> tn_sta;
		
		const TreeNode *p=root;
		while(p || !tn_sta.empty()){
			if(p){   //当前结点非空 
				res.push_back(p->val);
				tn_sta.push(p);
				p=p->left;	
			}
			else{    //当前结点为空,但栈非空 
				p=tn_sta.top(); 
				tn_sta.pop();
				p=p->right;	
			}
		}		
		return res;
    }
    vector<int> inorderTraversal(TreeNode *root) {
		vector<int> res;
		vector<const TreeNode *> sta;//vector模拟栈
		
		const TreeNode *p=root;
		while(p || !sta.empty()){
			if(p){     //当前结点非空 
				sta.push_back(p);
				p=p->left;
			}
			else{      //当前结点为空,但栈非空 
				p=sta.back();
				sta.pop_back();
				res.push_back(p->val);
				p=p->right;
			}
		}    
		return res;    
    }
    vector<int> postorderTraversal(TreeNode *root) {  	
    	vector<int> res;
		vector<TreeNode*> sta;	
			
		TreeNode *p=root,*q=NULL;//q记录根节点是否访问过 
		while(p || !sta.empty()) {
			if(p){
				sta.push_back(p);
				p=p->left;
			}else{
				p=sta.back();
				if(p->right==q){//右子树为空,或已访问过 
					sta.pop_back();//根节点出栈
					res.push_back(p->val);//根节点值记录到vector中			    
					q=p;//q回升到p 
					p=NULL;//p置空,防止死循环 
				}else{ //右子树未访问 
					q=p->right;//q下降到p的右结点 
					p=p->right;//p进入右子树访问 
				}
			}
		}
		return res;
    }
};
这里主要分析下后序遍历:

栈中的结点要在访问完其右子树后才能出栈,所以需要标记其右子树是否已经访问,最直接的想法是在数的结点定义中加一个变量标记其右子树是否访问,但这题中的树的结构已经给定,无法在其中添加新的成员变量。这里采用一个指针q来记录,q初值为空,若右子树未访问q随遍历指针p进入右子树,若右子树已访问或为空,则q退回到右子树的根结点。当根节点出栈后,不能忘记将p置空,否则死循环。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值