BST刪除節點


首先,BST節點的刪除分為幾種情況:
(a)當該節點為 葉子節點,則讓該節點的父節點指向其變為NULL,然后釋放節點;
(b)當該節點 不是葉子節點,但 左子樹或者右子樹為空,則:
        (1)若左子樹為空,則讓該節點父節點指向其右節點;
        (2)若右子樹為空,則讓該節點父節點指向其左節點。
(c)當該節點 不是葉子節點,且 左子樹和右子樹都不為空,則:
        (1)在該節點的左子樹中找到最大節點Lmax(該節點必然是一個葉子節點),取出Lmax的值val,刪除Lmax;
        (2)將 val 賦給該節點的值,即:root->val = val。
        (3)判斷Lmax的父節點PreLmax的左節點是否等於Lmax,若是則:PreLmax->left = Lmax->left    否則:  PreLmax->right = Lmax->left。
二叉搜索樹的刪除復雜度為O(h),h是二叉樹的高度。代碼如下:
/*刪除二叉搜索樹中的指定值的節點*/
node *deleteNode(node *root, int ele)
{
    node *newroot = root;  //指向新的根節點 
    node *presite = root; //指向要刪除節點的父節點 
    int pos = 0; //要刪除節點在其父節點的位置: -1:在左側    1:在右側    0:就是根節點  
    /*找到要刪除的元素在BST中的位置*/ 
    while(root != NULL)
    {
        if(root->val > ele)
        {
            presite = root;
            root = root->left;
            pos = -1;
        }
        else if(root->val < ele)
        {
            presite = root;
            root = root->right;
            pos = 1;
        }
        else
        {
            break;            
        }
    }
    if(root == NULL)
    {
        cerr<<"要刪除的節點不存在於BST中\n";
    }
    else
    {
        //該節點有左子樹和右子樹 
        if(root->left!=NULL && root->right!=NULL)
        {
            cout<<"has left and right tree\n";
            node *Lmax = root->left;    //最大左子節點 
            node *PreLmax = root;       //最大左子節點的父節點 
            while(Lmax->right != NULL)
            {
                PreLmax = Lmax;     
                Lmax = Lmax->right;
            }
            root->val = Lmax->val;    //替換root的值為最大左子樹節點值
            if(PreLmax->left == Lmax)  //root的左子樹最大節點是root的左節點 
                PreLmax->left = Lmax->left;
            else              //root的左子樹最大節點不是root的左節點
                PreLmax->right = Lmax->left;
            delete Lmax;
            Lmax = NULL;
        }
        //該節點的左子樹為空 
        else if(root->left == NULL && root->right != NULL)      
        {
            cout<<"left tree is empty\n";
            if(0 == pos)        //在根節點 
            {
                newroot = root->right;
            }
            else if(1 == pos)     //在右側 
            {    
                presite->right = root->right;
            }
            else                  //在左側 
            {
                presite->left = root->right;    
            }
            delete root;
            root = NULL;
        }
        //該節點的右子樹為空 
        else if(root->right == NULL && root->left != NULL)     //site的右子樹為空
        {
            cout<<"right tree is empty\n";
            if(0 == pos)      //在根節點 
            {
                newroot = root->left;
            }
            else if(1 == pos) //在右側 
            {
                presite->right = root->left;
            }
            else                //在左側 
            {
                presite->left = root->left;    
            }
            delete root;
            root = NULL;
        }
        //該節點為葉子節點 
        else                    
        { 
            cout<<"leaf node\n";
            if(0 == pos)          //根節點 
            {
                cerr<<"BST只有一個節點且被刪除,該BST變為空樹\n";
                delete root;
                root = NULL;
            }
            else if(1 == pos)      //在右側 
            {
                presite->right = NULL;
                delete root;
                root = NULL;
            }
            else                  //在左側 
            {
                presite->left = NULL;
                delete root;
                root = NULL;    
            }
        }    
    }
    return newroot;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM