由于课程设计,算法每天一个问题被迫中断了10天,今天放假,继续!
题目
给定一个二叉树,返回其节点的值的前序遍历。
例如,给定二叉树{1,#,2,3}
1
\
2
/
3
返回{1,2,3}
注意:递归解决方法很简单,如何用循环迭代来解决这个问题?
解析
树的遍历常用的方式有两种:递归和循环。递归最容易实现,但是限制性也很明显,即无法处理较大数据。面试的时候,更多还是关注在如何用while/for循环来实现树的3种遍历:前序、中序和后续。
如果用前序遍历作为例子,递归的方式是最直观的:
visit node
for the visited node, recursively
a. visit node->left
b. visit node->right
同时,递归代码也是最简洁的:
preorder(node)
if node == null then return
visit(node)
preorder(node.left)
preorder(node.right)
如果想要通过while/for循环来模拟前序遍历,往往要通过额外的栈或者队列来寄存访问节点。
前序遍历的伪代码可以表示为:
iterativePreorder(node)
parentStack = empty stack
parentStack.push(null)
top = node
while(top != null)
visit(top)
if(top.right != null)
parentStack.push(top.right)
if(top.left != null)
parentStack.push(top.left)
top = parentStack.pop()
同理,给出中序遍历、后序遍历的伪代码实现
中序遍历:
inorder(node)
if node == null then return
inorder(node.left)
visit(node)
inorder(node.right)
iterativeInorder(node)
parentStack = empty stack
while(! parentStack.isEmpty() || node != null)
if (node != null)
parentStack.push(node)
node = node.left
else
node = parentStack.pop()
visit(node)
node = node.right
后序遍历:
postorder(node)
if node == null then return
postorder(node.left)
postorder(node.right)
visit(node)
iterativePostorder(node)
parentStack = empty stack
while( ! parentStack.isEmpty() || node != null)
if(node != null)
parentStack.push(node)
node = node.left
else
peeknode = parentStack.peek()
if(peeknode.right != null && lastnodevisited != peeknode.right)
node = peeknode.right
else
parentStack.pop()
visit(peeknode)
lastnodevisited = peeknode
代码
vector<int> preorderTraversal(TreeNode *root){
stack<TreeNode*> tStack;
vector<int> result;
while(tStack.size() > 0 || root != NULL)
{
if(root != NULL)
{
result.push_back(root->val);
if(root->right != NULL)
tStack.push(root->right);
root = root->left;
}
else
{
root = tStack.top();
tStack.pop();
}
}
return result;
}