二叉搜尋樹中刪除某一結點函式的另外一種實現

2021-07-24 13:54:29 字數 1158 閱讀 1757

其實,還有另外一種思路來實現刪除結點這一操作。

假設我們要刪除的結點是u,可以發現,如果被刪結點u沒有左子樹,或者沒有右子樹,或者左右子樹都沒有的話,實際編碼過程中,被釋放的結點d就是結點u本身。

但是如果結點u的左右子樹均存在,實際編碼過程中,結點u改變的只是自身的關鍵值u->key,沒有被真正釋放。真正被釋放的結點d是結點u的右子樹中值最小的結點

(當然也可以是左子樹中值最大的結點,完全取決與你想如何實現)。因此,我們把關注點從結點u是否存在左右子樹,轉移到真正被釋放的結點d到底是什麼。

這就是實現刪除某一結點函式的新思路:

一、找到實際需要刪除並釋放的結點d

如果被刪結點u沒有左子樹,或者沒有右子樹,或者左右子樹都沒有,d = u

如果被刪結點u左右子樹均存在,d = u的右子樹中值最小的結點

二、找到結點d 的父結點f  與 d 的子結點s

三、重置結點f 的子結點

f == null , 說明結點d為根結點,根結點root = s(結點u左右子樹均存在時,d 的父結點f 一定存在,不會有這種情況)

否則將f 的子結點變為 s

四、釋放結點d

如果結點u左右子樹均存在(等價於d != u), u->key = d->key

最後釋放結點d

//刪除指定結點

void deletenode(tree_node &root, tree_node u)

//確定結點s

if (d->left != null) else

//確定結點f

tree_node x = root;

while (x != null && x != d)

if (x == null) return; //要刪除的結點不存在

//刪除並釋放結點d

if (f == null) root = s; //可以證明,這種情況下,結點u不可能同時存在左右子樹

else if (d == f->left)

f->left = s;

else

f->right = s;

if (d != u)

u->key = d->key; //結點u左右子樹均存在

free(d);

return;

}

刪除二叉搜尋樹中的某個結點

刪除操作的原型為 int deletebstree pnode proot,int data 返回型別int用來表示刪除是否成功,其中pnode表示如下 typedef int datatype typedef struct bstreenode node,pnode 刪除操作的原理為 首先在二叉搜...

二叉搜尋樹的建立 新增結點 刪除結點

bst t create void insert bst t tree,char key 小駝峰命名法 好習慣 建立新結點 treenode t newnode calloc 1,sizeof treenode t 用calloc好可以直接初始化為null,因為tree的左右子樹需要判斷是否為nul...

二叉搜尋樹 刪除二叉搜尋樹中的節點

這裡就把平衡二叉樹中刪除節點遇到的情況都搞清楚。第一種情況 沒找到刪除的節點,遍歷到空節點直接返回了 找到刪除的節點 第二種情況 左右孩子都為空 葉子節點 直接刪除節點,返回null為根節點 第三種情況 刪除節點的左孩子為空,右孩子不為空,刪除節點,右孩子補位,返回右孩子為根節點 第四種情況 刪除節...