1、递归遍历
1 void helper(TreeNode* root, vector<int>& res) { 2 if (root) { 3 res.push_back(root->val); 4 helper(root->left, res); 5 helper(root->right, res); 6 } 7 }
把3~5行按照访问顺序交换一下位置,就能实现前序遍历、中序遍历和后序遍历。
2、非递归遍历
非递归遍历可以用栈实现。
a. 前序遍历(144. Binary Tree Preorder Traversal)
前序遍历节点访问次序是 根-左-右
所以对于弹出的每一个节点,进栈顺序是先右孩子,再左孩子
1 class Solution { 2 public: 3 vector<int> preorderTraversal(TreeNode* root) { 4 vector<int> res; 5 stack<TreeNode*> stk; 6 if(root) 7 stk.push(root); 8 while (!stk.empty()) { 9 TreeNode *temp = stk.top(); 10 stk.pop(); 11 res.push_back(temp->val); 12 if (temp->right) 13 stk.push(temp->right); 14 if (temp->left) 15 stk.push(temp->left); 16 } 17 return res; 18 } 19 };
b. 中序遍历(94. Binary Tree Inorder Traversal)
中序遍历节点访问次序是 左-根-右
初始化,temp指向root
1、temp不为空,temp入栈,temp = temp -> left
2、temp为空,访问栈顶节点并出栈,temp = temp ->right
因为是先入栈,所以在出栈过程中,指针永远不能指回栈顶。
1 class Solution { 2 public: 3 vector<int> inorderTraversal(TreeNode* root) { 4 vector<int> res; 5 stack<TreeNode*> stk; 6 TreeNode *temp = root; 7 while(!stk.empty() || temp) { 8 if (temp) { 9 stk.push(temp); 10 temp = temp->left; 11 } 12 else { 13 temp = stk.top(); 14 stk.pop(); 15 res.push_back(temp->val); 16 temp = temp->right; 17 } 18 } 19 return res; 20 } 21 };
c. 后序遍历(145. Binary Tree Postorder Traversal)
后序遍历节点访问次序是 左-右-根
当以根-右-左形式遍历,出栈后的顺序刚好是倒着的后序遍历。操作方式跟前序遍历相同,只不过这回是左孩子先入栈。
可以把出栈节点再压入另一个栈,那么从栈2出去的节点顺序,就是后序遍历。
1 class Solution { 2 public: 3 vector<int> postorderTraversal(TreeNode* root) { 4 vector<int> res; 5 stack<TreeNode*> stk1; 6 stack<TreeNode*> stk2; 7 if(root) 8 stk1.push(root); 9 while(!stk1.empty()){ 10 TreeNode *temp = stk1.top(); 11 stk2.push(temp); 12 stk1.pop(); 13 if(temp->left) 14 stk1.push(temp->left); 15 if(temp->right) 16 stk1.push(temp->right); 17 } 18 while(!stk2.empty()) { 19 res.push_back(stk2.top()->val); 20 stk2.pop(); 21 } 22 return res; 23 } 24 };
还有一种用一个栈实现的,因为都是左节点先遍历,所以可以仿中序遍历思想,先把左节点入栈。但在根节点出栈时,要先判断右节点是否已经出栈,用一个变量记录之前出栈的点,如果之前出栈的是右节点,或右节点不存在,就可以把当前节点出栈,否则先把右节点入栈。
1 class Solution { 2 public: 3 vector<int> postorderTraversal(TreeNode* root) { 4 vector<int> res; 5 stack<TreeNode*> stk; 6 TreeNode *pre = nullptr; 7 TreeNode *curr = root; 8 while(!stk.empty() || curr){ 9 if(curr) { 10 stk.push(curr); 11 curr = curr->left; 12 } 13 else { 14 TreeNode *temp = stk.top(); 15 if (pre == temp->right || temp->right == nullptr) { 16 pre = stk.top(); 17 res.push_back(pre->val); 18 stk.pop(); 19 } 20 else { 21 curr = temp->right; 22 } 23 } 24 } 25 return res; 26 } 27 };