144. 二叉树的前序遍历
Given a binary tree, return the preorder traversal of its nodes' values.
Example:
Input:[1,null,2,3]1 \ 2 / 3 Output:[1,2,3]
Follow up: Recursive solution is trivial, could you do it iteratively?
二叉树的先序遍历。
这个比较简单,直接看递归和非递归的代码实现
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
process(root,list);
return list;
}
public void process(TreeNode node,List<Integer> list){
if(node==null){
return;
}
list.add(node.val);
process(node.left,list);
process(node.right,list);
}
}
先序遍历:中左右
非递归的方式用stack来实现(深度优先遍历用stack,广度优先用队列)
对当前节点压入stack,弹出并打印(中),再对cur压入右左(左右)
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
if(root==null){
return list;
}
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur=stack.pop();
list.add(cur.val);
if(cur.right!=null){
stack.push(cur.right);
}
if(cur.left!=null){
stack.push(cur.left);
}
}
return list;
}
}
先序遍历还可以用Morris序来遍历
时间复杂度为O(1)
Morris遍历细节:
假设cur来到当前节点,cur从头节点开始
1、cur没有左孩子,cur向右移动
2、cur有左孩子,找到左孩子的最右孩子
a:如果右孩子的右指针为空,则让右指针指向当前节点,当前节点向左移动,回到1;(表示第一次到这个节点)
b:如果右孩子的右指针指向当前节点,让右指针指向null,当前节点向右移动;(表示第二次到这个节点)
3、当cur为空遍历结束
这个过程说明了:如果cur有左孩子遍历时会两次经过该节点, 否则只会一次经过该节点
下面是Morris序遍历的代码:
public void morrisTraversal(TreeNode head){
if(head==null)
{
return;
}
TreeNode cur=head;
TreeNode mostRight;
while(cur!=null){
mostRight=cur.left;
if(mostRight!=null){
//有左节点
while (mostRight.right!=null&&mostRight.right!=cur){
mostRight=mostRight.right;
}
if(mostRight.right==null){
mostRight.right=cur;
cur=cur.left;
continue;
}else{
mostRight.right=null;
}
}
cur=cur.right;
}
}
Morris序改先序遍历
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
if(root==null){
return list;
}
TreeNode cur=root;
TreeNode mostRight;
while(cur!=null){
mostRight=cur.left;
if(mostRight!=null){
//有左节点
while (mostRight.right!=null&&mostRight.right!=cur){
mostRight=mostRight.right;
}
if(mostRight.right==null){
//第一次来到cur
list.add(cur.val);//注意这行的位置,不能放到下面,因为cur会移动
mostRight.right=cur;
cur=cur.left;
continue;
}else{
//第二次来到cur
mostRight.right=null;
}
}else{
//只会来到一次的cur
list.add(cur.val);
}
cur=cur.right;
}
return list;
}

浙公网安备 33010602011771号