作者:一樂樂
歡迎大家來一樂樂的博客園
歡迎大家來一樂樂的博客園
■ 前提是:中序遍歷才有所謂的前驅和后驅結點。
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. 后驅結點:中序遍歷時的后一個結點。
同理可得