【資料結構】二叉搜尋樹!!!

doctor_xiong發表於2018-03-08

二叉搜尋樹的結構類似於二分查詢的思想,在二叉樹結構裡面,將資料的大小分為樹的左右子樹,從而在搜尋的時候類似於二叉搜尋。
如圖:
這裡寫圖片描述
當搜尋一個二叉搜尋樹的時候時間複雜度就是O(logN).
構建搜尋二叉樹:

BSTree(int *arr,size_t size)
    :_root(NULL)
    {
        int index = 0;
        for(int i = 0;i<size;i++)
            _GreatNode(_root,arr,index++,size);
    }

    void _GreatNode(Node* root,int *arr,int index,size_t size){
        Node* tmp = new Node(arr[index]);
        if(root == NULL){
            _root = tmp;
            return;
        }
        int d = arr[index];
        Node* parent = NULL;
        while(root){
            parent = root;
            if(d < root->value)
                root = root->left;
            else
                root = root->right;
        }
        if(d < parent->value)
            parent->left = tmp;
        else
            parent->right = tmp;
    }

搜尋二叉樹的刪除
搜尋二叉樹的刪除分為以下幾種情況:

  • 當刪除的搜尋二叉樹為空樹 的時候
  • 當刪除的搜尋二叉樹只有右子樹的時候
  • 當刪除的搜尋二叉樹只有左子樹的時候
  • 當刪除的搜尋二叉樹的左右子樹都存在的時候

    注:這裡面的第一種情況可以和第二或者第三種情況進行合併

當二叉搜尋樹只有左子樹的時候:
這裡寫圖片描述

當二叉搜尋樹是由右子樹的時候:
這裡寫圖片描述

當二叉搜尋樹左右孩子都存在的時候:
這裡寫圖片描述

當二叉搜尋樹的左右子樹都存在的時候就可以在樹的左右子樹裡面尋找一個節點將需要刪除的結點的值進行替換,從而去刪除那個替換過的結點。

實現程式碼:

void _Del_Tree(Node* root,int key){
        if(NULL == root)
            return ;
        Node* tmp = find(key);
        Node* parent = _find_parent(_root,key);
        if(NULL == tmp)
            return ;
        if(tmp->left == NULL){   //當二叉搜尋樹的左孩子為空的時候
            if(tmp == _root)
                _root = tmp->right;
            else{
                if(tmp == parent->left)
                    parent->left = tmp->right;
                else
                    parent->right = tmp->right;
            }
            delete tmp;
        }
        else if(tmp->right == NULL){  //當二叉搜尋樹的右孩子為空的時候
            if(tmp == _root)
                _root = tmp->left;
            else{
                if(tmp == parent->left)
                    parent->left = tmp->left;
                else
                    parent->right = tmp->left;
            }
            delete tmp;
        }
        else{
            Node* pkey = NULL;
            //先尋找所有孩子裡面可以替換的孩子節點
            if(tmp->left->right){
                pkey = tmp->left->right;
                parent = tmp->left;
            }
            if(tmp->right->left){
                pkey = tmp->right->left;
                parent = tmp->right;
            }
            //當沒有找到可以替換的節點的時候直接進行交換刪除
            if(pkey == NULL){
                swap(tmp->value,tmp->right->value);
                Node* del = tmp->right;
                tmp->right = del->right;
                delete del;
            }
            else{ //當找到可以交換的孩子節點的時候將節點進行交換,然後繼續向下刪除交換的節點
                swap(pkey->value,tmp->value);
                _Del_Tree(root,key);
            }
        }
    }

相關文章