leetcode 题解:Binary Tree Preorder Traversal (二叉树的先序遍历)
题目:
Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [1,2,3]
.
Note: Recursive solution is trivial, could you do it iteratively?
说明:
1)递归和非递归实现,其中非递归有两种方法
2)复杂度,时间O(n),空间O(n)
实现:
一、递归
1 /** 2 * Definition for binary tree 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> root_vec; 14 vector<int> left_vec; 15 vector<int> right_vec; 16 if(root==NULL) return root_vec; 17 root_vec.push_back(root->val); 18 if(root->left!=NULL) left_vec=preorderTraversal(root->left); 19 if(root->right!=NULL) right_vec=preorderTraversal(root->right); 20 root_vec.insert(root_vec.end(),left_vec.begin(),left_vec.end()); 21 root_vec.insert(root_vec.end(),right_vec.begin(),right_vec.end()); 22 return root_vec; 23 } 24 };
二、非递归
根据先序遍历的顺序,先访问根节点,再访问左子树,后访问右子树,而对于每个子树来说,又按照同样的访问顺序进行遍历,非递归的实现思路如下:
对于任一节点P,
1)输出节点P,然后将其入栈,再看P的左孩子是否为空;
2)若P的左孩子不为空,则置P的左孩子为当前节点,重复1)的操作;
3)若P的左孩子为空,则将栈顶节点出栈,但不输出,并将出栈节点的右孩子置为当前节点,看其是否为空;
4)若不为空,则循环至1)操作;
5)如果为空,则继续出栈,但不输出,同时将出栈节点的右孩子置为当前节点,看其是否为空,重复4)和5)操作;
6)直到当前节点P为NULL并且栈空,遍历结束。
a、下面代码实现常规,和上面分析过程一致
1 /** 2 * Definition for binary tree 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> preorder_vec; 14 TreeNode *p=root;//定义用来指向当前访问的节点的指针 15 if(p==NULL) return preorder_vec;//若为空树,则返回空vector 16 stack<TreeNode *> treenode_stack;//创建一个空栈 17 //直到当前节点p为NULL且栈空时,循环结束 18 while(p||!treenode_stack.empty()) 19 { 20 //从根节点开始,输出当前节点,并将其入栈, 21 //同时置其左孩子为当前节点,直至其没有左孩子,及当前节点为NULL 22 preorder_vec.push_back(p->val); 23 treenode_stack.push(p); 24 p=p->left; 25 //如果当前节点p为NULL且栈不空,则将栈顶节点出栈, 26 //同时置其右孩子为当前节点,循环判断,直至p不为空 27 while(!p&&!treenode_stack.empty()) 28 { 29 p=treenode_stack.top(); 30 treenode_stack.pop(); 31 p=p->right; 32 } 33 } 34 } 35 };
b、下面代码实现较简洁(个人感觉,不喜勿喷)
1 /** 2 * Definition for binary tree 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 stack<TreeNode *> preorder_stack; 14 TreeNode *p=NULL; 15 vector<int> preorder_vec; 16 if(root==NULL) return preorder_vec;//若为空树,则返回空vector 17 preorder_stack.push(root);//当前节点入栈 18 while(!preorder_stack.empty()) 19 { 20 p=preorder_stack.top();//栈顶节点出栈、输出 21 preorder_stack.pop(); 22 preorder_vec.push_back(p->val); 23 //注意,下面入栈顺序不能错 ,因为先右后左, 24 //这样出栈时先遍历才是左孩子(左->中->右) 25 if(p->right) preorder_stack.push(p->right);//若存在右孩子,则入栈 26 if(p->left) preorder_stack.push(p->left);//若存在左孩子,则入栈 27 } 28 return preorder_vec; 29 } 30 };