94. Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree [1,null,2,3],
1
\
2
/
3
return [1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
嗯,经典的题目,中序遍历二叉树。题目说递归做起来太简单,请用迭代。我觉得还是先用递归做一下吧,也许我递归都不会呢?谁知道呢,是吧。然后发现,嗯,果然很简单,我好像已经不是从前那个菜逼了。
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
vector<int> vec;
public:
vector<int> inorderTraversal(TreeNode* root) {//中序遍历
if(root){
inorderTraversal(root->left);
vec.push_back(root->val);
inorderTraversal(root->right);
}
return vec;
}
vector<int> preorderTraversal(TreeNode* root){//先序遍历
if(root){
vec.push_back(root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
return vec;
}
vector<int> postorderTraversal(TreeNode* root){//后序遍历
if(root){
postorderTraversal(root->left);
postorderTraversal(root->right);
vec.push_back(root->val);
}
return vec;
}
};
是不是简单的不要不要的,递归就是这么美。
好了,现在想想怎么用迭代中序遍历呢。别想了,用栈吧,不用栈你做给我看试试。
层次遍历树相当于图的广度优先遍历(BFS,breadth first search),先序、中序、后序遍历二叉树都相当于图的深度优先遍历(DFS,depth first search)。要用迭代可以啊,广度优先请用队列,深度优先请用栈。
借助栈深度优先遍历时,首先我们压栈第一个结点(入口结点),然后又pop栈顶结点,我们把pop出来的结点的所有子节点都压进栈中,然后又是pop栈顶,继续进行如上操作。也许你发现了一个问题:没有说哪个孩子先压进栈,哪个后压栈,但有一点很明显,先压栈的会靠后访问,后压栈的会先被访问。
上代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
vector<int> vec;
stack<TreeNode*> s;
stack<TreeNode*> s1;
public:
vector<int> inorderTraversal(TreeNode* root) {//中序遍历
TreeNode* current=root;
while(!s.empty() || current!=NULL){
while(current){//如果结点存在,则入栈,然后判断左孩子
s.push(current);//越靠近root的越先压栈哦
current = current->left;
}
//往左走到了尽头,然后就是pop栈顶了
current = s.top();
s.pop();
vec.push_back(current->val);
//接着是判断右孩子
current = current->right;
}
return vec;
}
vector<int> preorderTraversal(TreeNode* root){//先序遍历
TreeNode* current=root;
while(!s.empty() || current!=NULL){
while(current){
vec.push_back(current->val);//遇到一个就先访问一个呗
s.push(current->right);//右孩子压栈,越靠近root的越先压栈哦
current = current->left;
}
current=s.top();
s.pop();
}
return vec;
}
//后序遍历,后序遍历就有点复杂了,需要两个栈,蛋疼。。。,
//什么你问我为啥多了一个栈,因为根节点要存起来啊,它非得要最后访问,就把它一脚踢进栈里。
vector<int> postorderTraversal(TreeNode* root){
TreeNode* current=root;
s.push(current);
while(!s.empty()){
current = s.top();
s.pop();
s1.push(current);//s1就是用来放后序遍历中的根结点的,root被压到最底下了,哈哈。s1放的是逆序打印顺序哦
if(current->left)
s.push(current->left);//左孩子先压栈,先压栈的后访问呐,左孩子不是应该先访问吗,拜托,后面要压入s1,顺序又反了。。
if(current->right)
s.push(current->right);//右孩子后压栈
}
while(!s1.empty()){//全部释放出来
vec.push_back(s1.top()->val);
s1.pop();
}
return vec;
}
};
嗯,总的来说用迭代遍历确实烧脑,没什么性能上的特殊需求还是用递归写法吧,对程序员友好哦。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。