1. 程式人生 > 其它 >前驅結點與後驅結點(前驅、後驅概念來源於中序遍歷)

前驅結點與後驅結點(前驅、後驅概念來源於中序遍歷)

前驅結點與後驅結點(前驅、後驅概念來源於中序遍歷)

前提是:中序遍歷才有所謂的前驅和後驅結點。

1. 前驅結點:中序遍歷時的前一個結點。

即:前驅結點(就是比當前結點小的前一個結點)。

(1) 哪個位置的結點有機會有前驅(根 和 右):

(2) “前一個結點”:需要離得最近。

①根(看左,找左區間最大的,離得近)

②右(看根,找根)

(3)方法(介面)public Node<E> predecessor(Node<E> node);

分析:public Node<E> predecessor(Node<E> node){    

        //當前傳入結點(可,需要判斷一下:是否有左(有左即可,不需要有右))

       node = node.left;

        //① 若node 非空:則作為“根”,去左區間找最大的

        //② 若node 空:找根(“父結點”),通過判斷是否構成“根-右”的關係。【找的過程是逆思維:因為需要遍歷 while(“根-左”), 跳出迴圈則是找到了“根-右”的關係】

   }

(4)具體程式碼:

// 內部類(一般是靜態內部類)
    private static class Node<E> {
        E elmement;
        Node<E> left;
        Node<E> right;
        
// 父結點(很有用) Node<E> parent; // 當你在外部傳入一個結點時,還可以直接指定父結點(但是該結點的左右結點還沒誕生,so。。。) public Node(E element, Node<E> parent) { this.elmement = element; this.parent = parent; } }
    // 前驅結點
    public Node<E> predecessor(Node<E> node) {
        
// 有左節點(left.right.right.right...) Node<E> p = node.left; if (p != null) { // while(p != null) 這樣會導致最後一個結點為null,此時 p = null while (p.right != null) { p = p.right; } return p; } // 沒有左節點(檢視找到第一個父結點的右結點等於當前結點) // 若一直是父節點左,就繼續上一層的父節點 while (node.parent != null && node.parent.left == node) { node = node.parent; } // 來到這裡:要麼父節點是null,要麼是 當前結點是父節點的右結點 return node.parent; }

2. 後驅結點:中序遍歷時的後一個結點。

同理可得