- 前序遍历
leetcode144前序遍历递归过程如下:
void inorderTraversal(TreeNode* root){ if(root==nullptr) return root; cout<<root->val<<endl; inorderTraversal(root->left); inorderTraversal(root->right); }
非递归
执行用时 :4 ms, 在所有 C++ 提交中击败了83.78%的用户内存消耗 :9 MB, 在所有 C++ 提交中击败了91.93%的用户
思路如下:前序遍历是根-左-右,把根也看成左孩子,cout<<root->val<<endl;inorderTraversal(root->left);就是不断存储数据以及不断访问左结点的过程,对应到while循环就是,存储当前结点,并入栈,继续访问左结点,直到左结点为空;inorderTraversal(root->right)可以看成是把当前右结点看成新的根节点,重新开启while循环的过程,对应的就是,t=S.top();S.pop();t=t->right;由于栈顶数据已经存储,所以需要出栈,再对右子树进行循环操作。vector<int> preorderTraversal(TreeNode* root) { vector<int> result; if(root==nullptr) return result; TreeNode* t=root; stack<TreeNode*> S; while(t || !S.empty()){ while(t){ result.push_back(t->val); S.push(t); t=t->left; } t=S.top(); S.pop(); t=t->right; } return result; }
- 中序遍历
leetcode94树的递归访问过程如下:
void inorderTraversal(TreeNode* root){ if(root==nullptr) return root; inorderTraversal(root->left); cout<<root->val<<endl; inorderTraversal(root->right); }
非递归
执行用时 :4 ms, 在所有 C++ 提交中击败了83.74%的用户内存消耗 :9.1 MB, 在所有 C++ 提交中击败了64.58%的用户
思路:中序遍历:左-根-右,inorderTraversal(root->left)这一语句可以借助一个while循环,不断把左孩子入栈,直到左孩子为空;cout<<root->val<<endl这一语句就是读取数据的过程,对应的就是t=S.top();result.push_back(t->val);S.pop();inorderTraversal(root->right)这一语句就是将右子树进行重复操作,那就是将右孩子看成新的根节点,重新开启while循环的过程,t=t->right;直到当前结点为空且栈也为空。vector<int> inorderTraversal(TreeNode* root) { vector<int> result; if(root==nullptr) return result; stack<TreeNode*> S; TreeNode* t=root; while(t || !S.empty()){ while(t){ S.push(t); t=t->left; } t=S.top(); result.push_back(t->val); S.pop(); t=t->right; } return result; }
- 后序遍历
后序遍历是左-右-根,后序遍历比较难做一些,但是,前序遍历好做啊,而两者又有相近之处,所以我们应该想着把后序遍历转换成前序遍历。推导一下就是,按照根据根-右-左的方式前序遍历,将数据入栈,那么栈低到栈顶数据顺序就是:根-右-左,存储完毕,将栈中数据出栈到向量后,向量里数据的顺序就是:左-右-根。
借助两个栈完成,一个栈跟前面前序遍历的作用相同,一个栈用来存储数据。执行用时 :4 ms, 在所有 C++ 提交中击败了82.57%的用户
内存消耗 :9.3 MB, 在所有 C++ 提交中击败了31.72%的用户
vector<int> postorderTraversal(TreeNode* root) { vector<int> result; if(root==nullptr) return result; stack<TreeNode*> S1; stack<int>S2; TreeNode *t=root; while(t || !S1.empty()){ while(t){ S2.push(t->val);//存储数据 S1.push(t); t=t->right; } t=S1.top(); S1.pop(); t=t->left; } while(!S2.empty()){ result.push_back(S2.top()); S2.pop(); } return result; }
关键是要能以正确的逻辑理解和分析问题,才能使用代码简洁地描述心中所想。
二叉树前序/中序/后序遍历非递归实现
最新推荐文章于 2023-01-19 14:14:12 发布