Java資料結構:二叉排序樹的刪除操作
阿新 • • 發佈:2018-12-16
嚶嚶嚶,今天補回昨天沒有寫的部落格。
二叉排序樹的刪除操作比較簡單,但是思想很全面,因此本人就寫一篇部落格紀念一下。
思想:四種類型也可以是三種
1,刪除結點p的度為2,即有左右子樹。
此時有兩種方法,第一種將結點的左子樹在中根遍歷下的最後一個結點放到p的位置。第二種是將p結點的右子樹在中根遍歷下的第一個結點放到p的位置。這裡本人根據之前的部落格二叉樹的中根遍歷就用了第二種方法。有first()方法,嚶嚶嚶。
2,單隻樹的根結點,且為葉子結點,度為1。
此時就需要將p的左子樹或右子樹(只有一個)替換p。so easy.
3,刪除結點p是度為1的葉子結點,有父母,是左孩子
此時需要將p的左孩子或者右孩子替換掉p。用p的孩子替換掉p。相信大家都會,類似於連結串列的插入。
4,刪除結點p是度為1的葉子結點,有父母,是右孩子。
此時需要將p的左孩子或者右孩子替換掉p。用p的孩子替換掉p。相信大家都會,類似於連結串列的插入。
上程式碼:
public T remove(T key) { TriNode<T> p = this.searchNode(key); // 查詢關鍵字為key元素,若查詢成功,返回結點,否則返回null if (p != null && p.left != null && p.right != null) // 找到待刪除結點p,若p是2度結點 { TriNode<T> insucc = this.first(p.right); // 尋找p在中根次序下的後繼結點insucc T temp = p.data; // 交換待刪除元素,作為返回值 p.data = insucc.data; // 以後繼結點值替換p結點值 insucc.data = temp; p = insucc; // 轉化為刪除insucc,刪除1、0度結點 } if (p != null && p == this.root) // p是1度或葉子結點,刪除根結點,p.parent==null { if (this.root.left != null) this.root = p.left; // 以p的左孩子頂替作為新的根結點 else this.root = p.right; // 以p的右孩子頂替作為新的根結點 if (this.root != null) this.root.parent = null; return p.data; // 返回被刪除根結點元素 } if (p != null && p == p.parent.left) // p是1度或葉子結點,p是父母的左孩子 if (p.left != null) { p.parent.left = p.left; // 以p的左孩子頂替 p.left.parent = p.parent; // p的左孩子的parent域指向p的父母 } else { p.parent.left = p.right; // 以p的右孩子頂替 if (p.right != null) p.right.parent = p.parent; } if (p != null && p == p.parent.right) // p是1度或葉子結點,p是父母的右孩子 if (p.left != null) { p.parent.right = p.left; // 以p的左孩子頂替 p.left.parent = p.parent; } else { p.parent.right = p.right; // 以p的右孩子頂替 if (p.right != null) p.right.parent = p.parent; } return p != null ? p.data : null; }