二叉查找樹重要性質:
(1)若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
(2)若右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
(3)左、右子樹也分別為二叉排序樹;
現有,如下一棵二叉查找樹。
(圖1)
現在,若要刪除圖1中,任意節點,需要考慮如下三種情況:
(1)需要刪除的節點下並沒有其他子節點。
(2)需要刪除的節點下有一個子節點(左或右)。
(3)需要刪除的節點下有兩個子節點(既左右節點都存在)。
第一種情況直接刪除即可,下面,直接討論第二種情況。
若我們要刪除的是3號節點,由圖1可以看到,它下面還有一個4號子節點。由下圖2,可以看出,對於這種辦法,我們只需要想辦法,讓5號節點的左子樹的指針指向4就可以了。
(圖2)
第三種情況,既我們要刪除的節點下,有2個子節點。如圖3,我們先在需要刪除的節點的右子樹中,找到一個最小的值(因為右子樹中的節點的值一定大於根節點)。然后,用找到的最小的值與需要刪除的節點的值替換。然后,再將最小值的原節點進行刪除(圖4)。
(圖3)
(圖4)
好了,思路大概就這樣了。下面見代碼。
- private Node<T> remove(T data,Node<T> node)
- {
- if(data == null)
- return node;
- /**
- * compare函數內部實現大致如下:
- * ((comparable)data).compareTo(node.element);
- * 比較需要刪除的數據與當前節點的值的大小
- */
- int result = compare(data,node.element);
- //result<0:表示需要刪除的節點在左子樹。(二叉查找數的性質)
- if(result<0)
- node.left = remove(data,node.left);
- else if(result>0)//在右子樹
- node.right = remove(data,node.right);
- else if(node.left != null && node.right != null)//找到需要刪除的節點且節點下有兩個子節點
- {
- /**先找到需要刪除的節點下,右子樹中最小的節點
- * 並將它的值賦給需要刪除的節點。
- * */
- node.element = findMin(node.right).element;
- //刪除前面找到的最小的節點。
- node.right = remove(node.right);
- }
- else//找到需要刪除的節點且節點下有一個子節點(左或者右)
- node = (node.left != null) ? node.left : node.right;
- }
- public void remove(T data)
- {
- this.remove(data,root);
- }
學習筆記。拍磚請輕拍。- -