标签:turn 递归算法 思想 treenode str vector 向量 empty tor
题目描述:
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3] 1 2 / 3 输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
数据结构定义:
struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} };
算法思想:
/*一、递归 效率较低,了解即可。 二叉树的中序遍历规则: 1. 遍历左子树; 2. 遍历右子树 3. 访问根结点; */ class Solution { private: void rec(TreeNode* root,vector<int> &ret){ if(root != NULL){ rec(root->left,ret); rec(root->right,ret); ret.push_back(root->val); } } public: vector<int> postorderTraversal(TreeNode* root) { vector<int> ret; rec(root,ret); return ret; } };
/* 二、迭代 效率较高,重点掌握。利用栈实现。对于节点p: 1. p如果是叶子节点,直接输出。 2. p如果有孩子,且孩子没有被访问过,则按照右孩子,左孩子的顺序依次入栈。(为了保证按照左孩子,右孩子的顺序弹出)。 3. p如果有孩子,而且孩子都已经访问过,则访问p节点。 为了分清返回的根节点时从左子树还是右子树返回的,增加辅助指针r,其指向最近访问过的结点。 拓展:当访问一个结点*p时,栈中结点恰好为*p结点的所有祖先。从栈底到栈底结点再加上*p结点,刚好构成从根节点到*p结点的一条路径。这一特性非常重要,如求根结点到某结点的路径;求两个结点的最近公共祖先;均可用这个思想。 */ class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> ret; if(root == NULL) //特殊情况,为空树 return ret; stack<TreeNode *> s; TreeNode *p = root; TreeNode *r = NULL; while(p||!s.empty()){ //结点不为空或栈中有元素 if(p){ //走到最左边 s.push(p); p=p->left; } else{ //向右 p=s.top(); //取栈顶结点 if(p->right && p->right!=r){ //如果右子树存在且未被访问过,则入栈 p=p->right; s.push(p); p=p->left; //再走到最左 } else{ //否则,则弹出结点并访问 s.pop(); //将结点弹出 ret.push_back(p->val); //访问结点,存入向量中 r=p; //记录最近访问过的结点 p=NULL; //结点访问完,重置p } } } return ret; } };
分析总结:
标签:turn 递归算法 思想 treenode str vector 向量 empty tor
原文地址:https://www.cnblogs.com/parzulpan/p/9920766.html