题目描述:
给定一个二叉树,返回它的中序 遍历。《大话数据结构》— “ 二叉树的遍历”
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
解题思路1:
按照left、mid、right的顺序递归的遍历二叉树
代码1:
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def __init__(self):
self.ret = []
def inorderTraversal(self, root):
if not root:
return []
if root.left:
self.inorderTraversal(root.left)
if root.val:
self.ret.append(root.val)
if root.right:
self.inorderTraversal(root.right)
return self.ret
写法2:
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def dfs(root):
if not root:
return
# 按照 左-打印-右的方式遍历
dfs(root.left)
res.append(root.val)
dfs(root.right)
dfs(root)
return res
解题思路2: 迭代实现
这题的真正难点在于如何用非递归的方式实现。 递归实现时,是函数自己调用自己,一层层的嵌套下去,操作系统/虚拟机自动帮我们用栈来保存了每个调用的函数,现在我们需要自己模拟这样的调用过程。
递归的调用过程是这样的:
dfs(root.left)
dfs(root.left)
dfs(root.left)
为null返回
打印节点
dfs(root.right)
dfs(root.left)
dfs(root.left)
........
递归的调用过程是不断往左边走,当左边走不下去了,就打印节点,并转向右边,然后右边继续这个过程。
我们在迭代实现时,就可以用栈来模拟上面的调用过程。
代码2:
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
stack = []
while stack or root:
# 不断往左子树方向走,每走一次就将当前节点保存到栈中
# 这是模拟递归的调用
if root:
stack.append(root)
root = root.left
# 当前节点为空,说明左边走到头了,从栈中弹出节点并保存
# 然后转向右边节点,继续上面整个过程
else:
tmp = stack.pop()
res.append(tmp.val)
root = tmp.right
return res
思路: 将整棵树的最左边一条链压入栈中,每次去除栈顶元素,如果他有右子树,则将其右子树压入栈中。
/**
* 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 {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode *> stk; //首先定义一个栈
auto p = root; //用p来遍历整棵树
while(p || stk.size())
{
while(p)
{
stk.push(p);
p = p -> left;
}
p = stk.top(); // 栈顶元素输出
stk.pop();
res.push_back(p -> val);
p = p -> right;
}
return res;
}
};
参考链接:
leetcode–94–二叉树的中序遍历
动画演示+三种实现 94. 二叉树的中序遍历
题目来源: