1. 程式人生 > 實用技巧 >一維陣列轉二叉樹、註解回滾、eclipse配置程式碼自動補全

一維陣列轉二叉樹、註解回滾、eclipse配置程式碼自動補全

最近對紅黑樹產生了興趣,想研究一波,找了篇文章說需要具備二叉查詢樹和完美平衡二叉樹的知識,我慌了... ...

怎麼辦呢?學一手吧,找了一篇二叉樹教學文章,然而它告訴我要先學遞迴演算法,遞迴這東西我知道,就是沒怎麼用過,理論懂點,實操手生。

先簡單回顧了一下遞迴,然後找了道經典習題熱熱身,再然後開始著手重學二叉樹,早知如此當初接觸這東西的時候就應該學好。

當我學習到二叉樹的儲存結構中的順序儲存時,產生了一個疑問,如何將一維陣列儲存為二叉樹結構?

通常學習進度到了這個地方我會選擇查一手百度,但是今天就是想用自己的思路硬懟一波。

我希望將陣列的第一個資料儲存在根節點,第二個資料儲存在根節點的左子節點,以此類推。

首先,搞一個節點類:

public class Node {
    private int nodeId; //心血來潮加了個id,沒必要
    private int nodeNum;
    private Node leftNode;
    private Node rightNode;

    public Node(int nodeId, int nodeNum) {
        this.nodeId = nodeId;
        this.nodeNum = nodeNum;
    }

    public Node getLeftNode() {
        
return leftNode; } public void setLeftNode(Node leftNode) { this.leftNode = leftNode; } public Node getRightNode() { return rightNode; } public void setRightNode(Node rightNode) { this.rightNode = rightNode; } @Override public String toString() { //最後列印看效果
return "Node{" + "nodeId=" + nodeId + ", nodeNum=" + nodeNum + '}'; } }

然後,搞了個數組轉二叉樹的構建類,名字半天想不出來,就先用builder吧,反正是練習起名隨意點吧。

public class NodeBuilder {

public Node rootNode = null;
public AtomicInteger adder = new AtomicInteger(1);
public static Queue<Node> queue = new ArrayDeque<>();

public NodeBuilder(int[] arr) {

if (arr.length == 0 || arr == null)
throw new RuntimeException("are you kidding?");

rootNode = new Node(adder.getAndAdd(1), arr[0]);
queue.add(rootNode);
for (int i = 1; i < arr.length; i++) {
Node node = queue.peek();
Node nextNode = new Node(adder.getAndAdd(1), arr[i]);

if (node.getLeftNode() != null && node.getRightNode() != null) {
queue.poll();
node = queue.peek();
}

if (node.getLeftNode() == null) {
node.setLeftNode(nextNode);
} else if (node.getRightNode() == null) {
node.setRightNode(nextNode);
}

queue.add(nextNode);
}
}
}

rootNode是根節點,AtomicInteger用於生成節點序號,佇列用於記錄節點引用。

我自己的思路就是維護一個佇列用於存放節點,首先建立根節點儲存陣列第一位資料,然後入隊。

後續的陣列資料開始遍歷,獲取佇列頭的節點但不出隊,判斷左節點是否有物件,沒有的話直接建立節點存進去。

左節點有物件的話,就繼續判斷右節點,關鍵在於每建立一個新節點都要入隊,因為後續還要往這些子節點中繼續存入節點。

當根節點存滿後,就會被出隊,然後獲取到的佇列頭節點就是根節點的左節點,因為入隊時是按照先左後右的順序。

最終搞了一個類測試一下:

public class Boot {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5,6,7,8,9,0};
        NodeBuilder nodeBuilder = new NodeBuilder(arr);
        System.out.println(nodeBuilder.rootNode);
        print(nodeBuilder.rootNode);
    }

    static void print(Node node) {
        if (node == null) {
            return;
        }
        if (node.getLeftNode() != null)
            System.out.println(node.getLeftNode());
        if (node.getRightNode() != null)
            System.out.println(node.getRightNode());

        print(node.getLeftNode());
        print(node.getRightNode());
    }
}

首先建立了一個樸實無華的整型陣列,然後轉為二叉樹,列印根節點,遞迴列印剩餘節點。

我這種遞迴好像叫深度優先搜尋吧,不太記得了,反正最終發現節點序號和陣列對的上,應該是沒啥問題,列印結果如下:

Node{nodeId=1, nodeNum=1}
Node{nodeId=2, nodeNum=2}
Node{nodeId=3, nodeNum=3}
Node{nodeId=4, nodeNum=4}
Node{nodeId=5, nodeNum=5}
Node{nodeId=8, nodeNum=8}
Node{nodeId=9, nodeNum=9}
Node{nodeId=10, nodeNum=0}
Node{nodeId=6, nodeNum=6}
Node{nodeId=7, nodeNum=7}

今天領導讓修改了一下專案中的@Transactional,改為@Transactional(rollbackFor=Exception.class),查了一下,就是丟擲異常後資料回滾,但是,我怎麼記得不加括號的內容它也回滾呢?

這個改天研究吧 ... ...

最後,記錄一個eclipse小技巧,配置程式碼補全:

進入eclipse——>點選window——>點選preferences——>點選java——>點選editor——>點選content assist——>修改如圖所示的內容:

.AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz

改好後apply一下什麼的,就可以了。