递归 效率极高

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List preorderTraversal(TreeNode root) {
        List ls = new LinkedList();
        per(root, ls);
        return ls;
    }
    public static void per(TreeNode T, List ls) {
        if (T != null) {
            ls.add(T.val);
            if (T.left != null)
                per(T.left, ls);
            if (T.right != null)
                per(T.right, ls);
        }
    }
}

用了递推接出来 但是效率不高

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List preorderTraversal(TreeNode root) {
        List ls = new LinkedList();
        Stack queue = new Stack();
        queue.add(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.pop();
            if (node != null) {
                ls.add(node.val);
                if (node.right != null)
                    queue.add(node.right);
                if (node.left != null)
                    queue.add(node.left);
            }
        }
        return ls;
    }
}

莫里斯遍历 不懂

方法 2:莫里斯遍历
方法基于 莫里斯的文章,可以优化空间复杂度。算法不会使用额外空间,只需要保存最终的输出结果。如果实时输出结果,那么空间复杂度是 O(1)O(1)。
算法
算法的思路是从当前节点向下访问先序遍历的前驱节点,每个前驱节点都恰好被访问两次。
首先从当前节点开始,向左孩子走一步然后沿着右孩子一直向下访问,直到到达一个叶子节点(当前节点的中序遍历前驱节点),所以我们更新输出并建立一条伪边 predecessor.right = root 更新这个前驱的下一个点。如果我们第二次访问到前驱节点,由于已经指向了当前节点,我们移除伪边并移动到下一个顶点。
如果第一步向左的移动不存在,就直接更新输出并向右移动。

class Solution {
  public List preorderTraversal(TreeNode root) {
    LinkedList output = new LinkedList();
    TreeNode node = root;
    while (node != null) {
      if (node.left == null) {
        output.add(node.val);
        node = node.right;
      }
      else {
        TreeNode predecessor = node.left;
        while ((predecessor.right != null) && (predecessor.right != node)) {
          predecessor = predecessor.right;
        }
        if (predecessor.right == null) {
          output.add(node.val);
          predecessor.right = node;
          node = node.left;
        }
        else{
          predecessor.right = null;
          node = node.right;
        }
      }
    }
    return output;
  }
}