树的各种遍历实现
树的遍历有前序,后序,广度,以及中序遍历。下边将利用递归以及非递归的方式实现这几种遍历方式。
1.前序遍历
递归写法:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> preorderTraversal(TreeNode* root) { 13 vector<int> res; 14 Traversal(root, res); 15 return res; 16 } 17 18 void Traversal(TreeNode *root, vector<int> &res) 19 { 20 if(!root) return ; 21 res.push_back(root->val); 22 Traversal(root->left, res); 23 Traversal(root->right, res); 24 } 25 };
非递归写法:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> preorderTraversal(TreeNode* root) { 13 vector<int> res; 14 if(!root) return res; 15 stack<TreeNode *>stk; 16 stk.push(root); 17 18 while(!stk.empty()){ 19 TreeNode* s = stk.top(); 20 stk.pop(); 21 res.push_back(s->val); 22 if(s->right) stk.push(s->right); 23 if(s->left) stk.push(s->left); 24 } 25 26 return res; 27 } 28 };
非递归写法主要要弄清楚树遍历的顺序,这样就很容易写出来相应的stack的压出栈顺序。
2.中序遍历
递归写法
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> inorderTraversal(TreeNode* root) { 13 vector<int> res; 14 Traversal(root, res); 15 return res; 16 } 17 18 void Traversal(TreeNode *root, vector<int> &res) 19 { 20 if(!root) return ; 21 Traversal(root->left, res); 22 res.push_back(root->val); 23 Traversal(root->right, res); 24 } 25 };
非递归写法
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> inorderTraversal(TreeNode* root) { 13 vector<int> res; 14 if(!root) return res; 15 TreeNode *cur = root; 16 stack<TreeNode *>stk; 17 18 while(cur || !stk.empty()){ 19 if(cur){ 20 stk.push(cur); 21 cur = cur->left; 22 }else{ 23 cur = stk.top(); 24 stk.pop(); 25 res.push_back(cur->val); 26 cur = cur->right; 27 } 28 } 29 30 return res; 31 } 32 };
非递归写法要注意stack弹出栈的操作,这里的思路是这样的:当左边没有元素时弹出,但是弹出后如果右边不是空则压入右边,如果右边为空则继续弹出,也就成了以上所写的代码了。这里无法使用前序遍历那种仅仅根据压栈出栈的顺序写stack的原因在于前序本质还是从上至下的,不会产生重复遍历的过程。而中序从下至上,如果仅仅push(left), push(mid),push(right)这种方法会导致重复访问节点的问题。
3.后序遍历
递归写法
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> postorderTraversal(TreeNode* root) { 13 vector<int> res; 14 Traversal(root, res); 15 return res; 16 } 17 18 void Traversal(TreeNode *root, vector<int> &res) 19 { 20 if(!root) return ; 21 Traversal(root->left, res); 22 Traversal(root->right, res); 23 res.push_back(root->val); 24 } 25 };
非递归写法:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> postorderTraversal(TreeNode* root) { 13 TreeNode *cur = root; 14 vector<int> res; 15 if(!root) return res; 16 stack<TreeNode *>stk; 17 18 stk.push(root); 19 while(!stk.empty()){ 20 TreeNode *t = stk.top(); 21 stk.pop(); 22 res.push_back(t->val); 23 if(t->left) 24 stk.push(t->left); 25 if(t->right) 26 stk.push(t->right); 27 } 28 reverse(res.begin(), res.end()); 29 return res; 30 } 31 };
非递归写法利用前序遍历的思想进行编写,然后进行reverse。因为前序遍历中弹出的条件更容易判断,用完就可以弹出。所以利用前序遍历更容易
4.广度搜索
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<vector<int>> levelOrder(TreeNode* root) { 13 vector<vector<int> >res; 14 15 queue<TreeNode *> q; 16 if(!root) return res; 17 q.push(root); 18 19 while(!q.empty()){ 20 int count = q.size(); 21 vector<int> r; 22 while(count){ 23 TreeNode *t = q.front(); 24 r.push_back(t->val); 25 q.pop(); 26 if(t->left) q.push(t->left); 27 if(t->right) q.push(t->right); 28 count--; 29 } 30 res.push_back(r); 31 } 32 33 return res; 34 } 35 };
利用队列实现。