1. 程式人生 > 遊戲攻略 >《原神攻略》高配四風速切隊玩法講解

《原神攻略》高配四風速切隊玩法講解

一、遞迴方式遍歷

遞迴方法完成二叉樹的遍歷,每一個節點都能回去3次(雖然某一次回去的時候什麼也沒幹)

在遞迴序的基礎上,選擇列印的時機不同可演變出前序、中序、後續三種遍歷方式

前序-列印遞迴遍歷時第1次出現的數字(頭左右):1,2,4,5,3,6,7

中序-列印遞迴遍歷時第2次出現的數字(左頭右):4,2,5,1,6,3,7

後續-列印遞迴遍歷時第3次出現的數字(左右頭):4,5,2,6,7,3,1

    public static void preOrderRecur(Node head) {
        if (head == null) {
            return
; } System.out.print(head.value + " "); //此位置為前序遞迴 preOrderRecur(head.left); //System.out.print(head.value + " "); //此位置為中序遞迴 preOrderRecur(head.right); //System.out.print(head.value + " "); //此位置為後序遞迴 }
前序遞迴遍歷

二、非遞迴方式遍歷

1、前序遍歷

先把頭節點放入棧中

1)每次在棧中彈出一個節點,記為cur

2)列印(處理)cur

3)如有cur有左右孩子(沒有孩子就不操作,繼續步驟1),先把cur右孩子壓棧,再把cur左孩子壓棧

4)迴圈以上三步操作

   //前序非遞迴
    public static void preOrderUnRecur(Node head) {
        System.out.print("pre-order: ");
        if (head != null) {
            Stack<Node> stack = new Stack<Node>();
            stack.add(head);  
//先把頭節點壓入棧中 while (!stack.isEmpty()) { //只要棧不是空的,迴圈3個步驟 head = stack.pop(); System.out.print(head.value + " "); if (head.right != null) { stack.push(head.right); } if (head.left != null) { stack.push(head.left); } } } System.out.println(); }
前序非遞迴遍歷

2、後續遍歷

由前序遍歷進行改進而來:

準備兩棧(多一個收集棧),先把頭節點放入正常棧中

1)每次在正常棧中彈出一個節點,記為cur

2)把cur放入一個收集棧中

3)如有cur有左右孩子(沒有孩子就不操作,繼續步驟1),先把cur孩子壓入正常棧,再把cur孩子壓正常棧

迴圈以上三步操作

4)再把收集棧中的元素依次彈出就是後續遍歷結果

//後序非遞迴
    public static void posOrderUnRecur1(Node head) {
        System.out.print("pos-order: ");
        if (head != null) {
            Stack<Node> s1 = new Stack<Node>(); //正常棧
            Stack<Node> s2 = new Stack<Node>(); //收集棧
            s1.push(head); //先壓入頭節點
            while (!s1.isEmpty()) { //迴圈1/2/3
                head = s1.pop(); //1、每次彈出一個元素
                s2.push(head); //2、彈出之後不列印,而是放入收集棧中
                if (head.left != null) {
                    s1.push(head.left); //3、先壓左節點
                }
                if (head.right != null) {
                    s1.push(head.right); //3、再壓右節點
                }
            }
            while (!s2.isEmpty()) {
                System.out.print(s2.pop().value + " "); //4、最後把收集棧中的元素彈出進行列印
            }
        }       
    }
後續非遞迴遍歷

3、中序遍歷

1)把當前節點的所有左節點壓棧

2)依次彈出節點的過程中,列印

3)每彈出一個節點,把目標移到彈出節點的右節點上面

迴圈以上三個操作

//中序非遞迴
    public static void inOrderUnRecur(Node head) {
        System.out.print("in-order: ");
        if (head != null) {
            Stack<Node> stack = new Stack<Node>();
            while (!stack.isEmpty() || head != null) {
                if (head != null) { //1、把當前節點所有的左節點壓棧
                    stack.push(head);
                    head = head.left;
                } else { //所有左節點壓棧之後
                    head = stack.pop(); //2、彈出一個節點,列印
                    System.out.print(head.value + " ");
                    head = head.right; //3、然後移動到彈出節點的右節點上面,迴圈以上步驟
                }
            }
        }
    }
中序非遞迴遍歷

為什麼進行以上三步操作就能實現前中後的中序遍歷?

整體程式碼

package Algorithms;

/**
 * @author : zhang
 * @version : 1.0
 * @date : Create in 2021/8/11
 * @description :
 */

import java.util.Stack;

public class PreInPosTraversal {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

    //前序遞迴
    public static void preOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        System.out.print(head.value + " ");
        preOrderRecur(head.left);
        preOrderRecur(head.right);
    }

    //中序遞迴
    public static void inOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        inOrderRecur(head.left);
        System.out.print(head.value + " ");
        inOrderRecur(head.right);
    }

    //後序遞迴
    public static void posOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        posOrderRecur(head.left);
        posOrderRecur(head.right);
        System.out.print(head.value + " ");
    }

    //前序非遞迴
    public static void preOrderUnRecur(Node head) {
        System.out.print("pre-order: ");
        if (head != null) {
            Stack<Node> stack = new Stack<Node>();
            stack.add(head);  //先把頭節點壓入棧中
            while (!stack.isEmpty()) { //只要棧不是空的,迴圈3個步驟
                head = stack.pop();
                System.out.print(head.value + " ");
                if (head.right != null) {
                    stack.push(head.right);
                }
                if (head.left != null) {
                    stack.push(head.left);
                }
            }
        }
        System.out.println();
    }

    //中序非遞迴
    public static void inOrderUnRecur(Node head) {
        System.out.print("in-order: ");
        if (head != null) {
            Stack<Node> stack = new Stack<Node>();
            while (!stack.isEmpty() || head != null) {
                if (head != null) { //1、把當前節點所有的左節點壓棧
                    stack.push(head);
                    head = head.left;
                } else { //所有左節點壓棧之後
                    head = stack.pop(); //2、彈出一個節點,列印
                    System.out.print(head.value + " ");
                    head = head.right; //3、然後移動到彈出節點的右節點上面,迴圈以上步驟
                }
            }
        }
    }

    //後序非遞迴
    public static void posOrderUnRecur1(Node head) {
        System.out.print("pos-order: ");
        if (head != null) {
            Stack<Node> s1 = new Stack<Node>(); //正常棧
            Stack<Node> s2 = new Stack<Node>(); //收集棧
            s1.push(head); //先壓入頭節點
            while (!s1.isEmpty()) { //迴圈1/2/3
                head = s1.pop(); //1、每次彈出一個元素
                s2.push(head); //2、彈出之後不列印,而是放入收集棧中
                if (head.left != null) {
                    s1.push(head.left); //3、先壓左節點
                }
                if (head.right != null) {
                    s1.push(head.right); //3、再壓右節點
                }
            }
            while (!s2.isEmpty()) {
                System.out.print(s2.pop().value + " "); //4、最後把收集棧中的元素彈出進行列印
            }
        }
        System.out.println();
    }

    public static void posOrderUnRecur2(Node h) {
        System.out.print("pos-order: ");
        if (h != null) {
            Stack<Node> stack = new Stack<Node>();
            stack.push(h);
            Node c = null;
            while (!stack.isEmpty()) {
                c = stack.peek();
                if (c.left != null && h != c.left && h != c.right) {
                    stack.push(c.left);
                } else if (c.right != null && h != c.right) {
                    stack.push(c.right);
                } else {
                    System.out.print(stack.pop().value + " ");
                    h = c;
                }
            }
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Node head = new Node(1);
        head.left = new Node(2);
        head.right = new Node(3);
        head.left.left = new Node(4);
        head.left.right = new Node(5);
        head.right.left = new Node(6);
        head.right.right = new Node(7);


        // recursive
        System.out.println("==============recursive==============");
        System.out.print("pre-order: ");
        preOrderRecur(head);
        System.out.println();
        System.out.print("in-order: ");
        inOrderRecur(head);
        System.out.println();
        System.out.print("pos-order: ");
        posOrderRecur(head);
        System.out.println();

        // unrecursive
        System.out.println("============unrecursive=============");
        preOrderUnRecur(head);
        inOrderUnRecur(head);
        posOrderUnRecur1(head);
        posOrderUnRecur2(head);
    }
}

/**
 * ==============recursive==============
 * pre-order: 1 2 4 5 3 6 7
 * in-order: 4 2 5 1 6 3 7
 * pos-order: 4 5 2 6 7 3 1
 * ============unrecursive=============
 * pre-order: 1 2 4 5 3 6 7
 * in-order: 4 2 5 1 6 3 7
 * pos-order: 4 5 2 6 7 3 1
 * pos-order: 4 5 2 6 7 3 1
 */