一 .二叉排序樹
定義: 左子樹的值小於父節點的值,右子樹的值大於父節點的值,所有節點都滿足此定義。
刪除: 分三種情況
① 刪除的節點爲葉子節點,那麼直接刪除即可。對整棵樹沒什麼影響
②刪除的節點有只有左子樹或者右子樹,把該子樹往上移就好
③刪除的節點既有左子樹也有右子樹,假設刪除的節點爲p,那麼根據二叉樹的性質(中序遍歷的結果從小到大),需要找到p節點的前驅(比p小的最大節點)或者後繼(比p大的最小節點)去代替p節點。也就是p的左子樹的右子樹的右子樹。。或者p的右子樹的的左子樹左子樹。。。。
這裏可以這樣理解:假設我們想不動p的右子樹,在其左子樹中找一個節點去替代p節點,那麼爲了維護二叉樹的性質,我們就需要找p的左子樹中節點值最大的一個,那麼就是左子樹的右子樹的右子樹。。。,也就是左子樹中最右邊的一個節點。假設最右節點是q,那麼這個節點肯定是沒有右子樹的,因爲如果還存在右子樹,那麼就是說還存在比q還要大得多節點。
所以把q節點的值給p節點,然後把q的左子樹給q的父節點,再刪除q節點即可。
java代碼:
public class BinaryTree {
private Node root;
public class Node{
int val;
Node leftChild,rightChild;
Node(int val){
this.val = val;
leftChild=null;
rightChild = null;
}
}
BinaryTree(){
root = null;
}
public void insert(int data) {
Node newNode = new Node(data);
if(root == null) root = newNode;
else {
Node cur = root;
while (true) {
if (data < cur.val) {
if (cur.leftChild == null) {
cur.leftChild = newNode;
break;
}
cur = cur.leftChild;
} else {
if (cur.rightChild == null) {
cur.rightChild = newNode;
break;
}
cur = cur.rightChild;
}
}
}
}
public Node find(int data) {
Node cur = root;
while (cur != null) {
if (cur.val == data) return cur;
if (data < cur.val) cur = cur.leftChild;
else cur = cur.rightChild;
}
return null;
}
public Node dele(int data){
return dele(root,data);
}
//刪除
private Node dele(Node p, int data) {
if (p == null) return null;
if (data < p.val) p.leftChild = dele(p.leftChild, data);
else if (data > p.val) p.rightChild = dele(p.rightChild, data);
else if(p.leftChild==null){
if( root == p)
root = p.rightChild;
return p.rightChild;
}
else if(p.rightChild==null){
if(root == p)
root = p.leftChild;
return p.leftChild;
}
else{
Node cur = p.leftChild,pre = p;
while(cur.rightChild != null){
pre = cur;
cur = cur.rightChild;
}
p.val = cur.val;
if(pre==p)p.leftChild = cur.leftChild;
else pre.rightChild = cur.leftChild;
cur = null;
}
return p;
}
//打印節點值 中序遍歷
public void printVal(){
printVal(root);
}
private void printVal(Node p) {
if (p == null) return;
printVal(p.leftChild);
System.out.print(p.val + " ");
printVal(p.rightChild);
}
}