public static void visit(TreeNode p) {
System.out.print(p.val + " ");
}.net
//**********遞歸的先序遍歷**********
public static void recursivePreOrder(TreeNode p) {
if (p == null) return;
visit(p);
recursivePreOrder(p.left);
recursivePreOrder(p.right);
}blog
//**********遞歸的中序遍歷**********
public static void recursiveInOrder(TreeNode p) {
if (p == null) return;
recursiveInOrder(p.left);
visit(p);
recursiveInOrder(p.right);
}遞歸
//**********遞歸的後序遍歷**********
public static void recursivePostOrder(TreeNode p) {
if (p == null) return;
recursivePostOrder(p.left);
recursivePostOrder(p.right);
visit(p);
}get
//**********非遞歸的先序遍歷**********
//手算的思想,先變訪問邊找,找到最左下方的,而後向上再向訪問右邊的
public static void iterativePreOrder(TreeNode p) {
if (p == null) return;
Stack<TreeNode> stack = new Stack<TreeNode>();
while (!stack.empty() || p != null) {
while (p != null) {
visit(p);
stack.push(p);
p = p.left;
}
p = stack.pop();
p = p.right;
}
}it
//**********非遞歸的先序遍歷**********
//棧的思想,按層次倒着進棧,利用後進先出解決順序問題
public static void iterativePreOrder_2(TreeNode p) {
if (p == null) return;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(p);
while (!stack.empty()) {
p = stack.pop();
visit(p);
if (p.right != null) stack.push(p.right);
if (p.left != null) stack.push(p.left);
}
}List
//**********非遞歸的中序遍歷**********
public static void iterativeInOrder(TreeNode p) {
if (p == null) return;
Stack<TreeNode> stack = new Stack<TreeNode>();
while (!stack.empty() || p != null) {
while (p != null) {
stack.push(p);
p = p.left;
}
p = stack.pop();
visit(p);
p = p.right;
}
}遍歷
//**********非遞歸的後序遍歷**********
//注意prev的做用
public static void iterativePostOrder(TreeNode p) {
if (p == null) return;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode prev = p;
while (!stack.empty() || p != null) {
while (p != null) {
stack.push(p);
p = p.left;
}
p = stack.peek().right;
if (p == null || p == prev) {
//若棧頂節點的右節點爲空或者已經visit過,則按順序應該訪問棧頂節點
p = stack.pop();
visit(p);
//prev用來標記已經visit過這個節點
prev = p;
p = null;
}
}
}queue
//**********非遞歸的後序遍歷**********
//和上一種方法思想相似
public static void iterativePostOrder_2(TreeNode p) {
if (p == null) return;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode prev = p;
while (p != null) {
while (p.left != null) {
stack.push(p);
p = p.left;
}
while (p != null && (p.right == null || p.right == prev)) {
visit(p);
prev = p;
if (stack.empty()) return;
p = stack.pop();
}
stack.push(p);
p = p.right;
}
}方法
//**********非遞歸的後序遍歷**********
//雙棧法,易於理解
public static void iterativePostOrder_3(TreeNode p) {
if (p == null) return;
Stack<TreeNode> stack = new Stack<TreeNode>();
Stack<TreeNode> result = new Stack<TreeNode>();
while (!stack.empty() || p != null) {
while (p != null) {
stack.push(p);
result.push(p);
p = p.right;
}
if (!stack.empty()) p = stack.pop().left;
}
while (!result.empty()) {
p = result.pop();
visit(p);
}
}static
//**********非遞歸的層次遍歷**********
public static void iterativeLevelOrder(TreeNode p) {
if (p == null) return;
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(p);
while (!queue.isEmpty()) {
p = queue.poll();
if (p.left != null) queue.offer(p.left);
if (p.right != null) queue.offer(p.right);
visit(p);
}
}
//**********非遞歸的分層輸出的層次遍歷**********
public static void iterativeLevelOrder_1(TreeNode p) {
if (p == null) return;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(p);
while (!queue.isEmpty()) {
int levelNum = queue.size();
for (int i = 0; i < levelNum; i++) {
p = queue.poll();
if (p.left != null) queue.offer(p.left);
if (p.right != null) queue.offer(p.right);
visit(p);
}
System.out.println();
}
}
//**********非遞歸的分層輸出的層次遍歷**********
//維護兩個int,表明上一層和下一層的節點數量,上一層遍歷結束以後lineUp = lineDown; lineDown = 0;
public static void iterativeLevelOrder_2(TreeNode p) {
if (p == null) return;
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
int lineUp = 1, lineDown = 0;
queue.offer(p);
while (!queue.isEmpty()) {
p = queue.poll();
visit(p);
if (p.left != null){
queue.offer(p.left);
lineDown++;
}
if (p.right != null){
queue.offer(p.right);
lineDown++;
}
if (--lineUp == 0) {
lineUp = lineDown;
lineDown = 0;
System.out.println();
}
}
}
//**********遞歸的層次遍歷訪問**********
public static void recurLevelOrder(TreeNode root) {
if (root == null) return;
int depth = maxDepth(root);
//若是要倒序訪問只需修改此處順序
for (int i = 1; i <= depth; i++) visitNodeAtDepth(root, i);
}
//訪問特定層的節點
public static void visitNodeAtDepth(TreeNode p, int depth) {
if (p == null || depth < 1) return;
//由於要按順序訪問(打印),因此要規定必須到某一層才能visit
if (depth == 1) {
visit(p);
return;
}
//每次都要遍歷depth之上的全部層
visitNodeAtDepth(p.left, depth - 1);
visitNodeAtDepth(p.right, depth - 1);
}
//獲得樹的層數
public static int maxDepth(TreeNode root) {
if (root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
//**********遞歸的倒序層次遍歷並保存結果至list**********
//LeetCode107
//之因此用LinkedList是由於有addFirst()方法,能夠逆序保存
public static List<List<Integer>> recursiveLevelOrderBottom(TreeNode root) {
LinkedList<List<Integer>> lists = new LinkedList<List<Integer>>();
addToList(lists, root, 1);
return lists;
}
//將depth層的p節點保存至list
public static void addToList(LinkedList<List<Integer>> lists, TreeNode p, int depth) {
if (p == null) return;
if (lists.size() < depth) lists.addFirst(new LinkedList<Integer>());
//因爲不用輸出只是保存,能夠使用get控制保存在哪一層,因此不用規定層數
lists.get(lists.size() - depth).add(p.val);
addToList(lists, p.left, depth + 1);
addToList(lists, p.right, depth + 1);
}
}
https://blog.csdn.net/wayne566/article/details/79106372