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


 

 

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

 

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. 后驅結點:中序遍歷時的后一個結點。

 同理可得

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM