其實,還有另外一種思路來實現刪除結點這一操作。
假設我們要刪除的結點是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為根節點 第三種情況 刪除節點的左孩子為空,右孩子不為空,刪除節點,右孩子補位,返回右孩子為根節點 第四種情況 刪除節...