數據結構(樹)

一 .二叉排序樹

定義: 左子樹的值小於父節點的值,右子樹的值大於父節點的值,所有節點都滿足此定義。

刪除: 分三種情況
① 刪除的節點爲葉子節點,那麼直接刪除即可。對整棵樹沒什麼影響
②刪除的節點有只有左子樹或者右子樹,把該子樹往上移就好
③刪除的節點既有左子樹也有右子樹,假設刪除的節點爲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);
    }
}

發佈了70 篇原創文章 · 獲贊 6 · 訪問量 7426
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章