在二叉搜索樹查找(請戳我)一文中主要介紹了二叉搜索樹的查找,本文將繼續介紹其插入和刪除操做。二叉搜索樹的插入和刪除關鍵在於在插入和刪除的過程當中如何繼續保持二叉搜索樹的性質。
二叉搜索樹結點定義以下:算法
typedef struct BSTreeNode{ Type key; // 關鍵字(鍵值) struct BSTreeNode *left; // 左孩子 struct BSTreeNode *right; // 右孩子 struct BSTreeNode *parent; // 父結點 }Node, *BSTree;
插入結點的位置對應着查找過程當中查找不成功時候的結點位置,所以須要從根結點開始查找帶插入結點位置,找到位置後插入便可。下圖所示插入結點過程:服務器
插入結點代碼以下數據結構
//往樹tree的插入結點z Node* bstree_insert(BSTree tree, Node *z) { Node *y = NULL; Node *x = tree; // 查找z的插入位置 while (x != NULL) { y = x; if (z->key < x->key) x = x->left; else x = x->right; } z->parent = y; if (y==NULL) tree = z; else if (z->key < y->key) y->left = z; else y->right = z; return tree; }
二叉搜索樹刪除結點能夠說是二叉搜索樹中最爲複雜的操做,要考慮的狀況比較多,下面分狀況討論。
(1)要刪除的結點z爲葉子結點,這是最簡單的一種狀況,直接修改其父節點相應指針爲NULL。刪除過程以下圖所示:ide
(2)要刪除的結點z爲只有一個子樹,讓z的子樹與z的父親節點相連,刪除z便可,刪除過程以下圖所示:函數
(3)要刪除的結點z爲有兩個子樹,則先找到z的後繼結點y,y確定是沒有左子樹的(若是y還有左子樹,那麼y就確定不是z的後繼結點),因此如今能夠按照上面兩種狀況刪除y結點,最後用y的值代替z的值。整個刪除過程以下圖所示:指針
二叉搜索樹刪除結點的代碼實現以下。code
//刪除樹tree的結點z Node* bstree_delete(BSTree tree, Node *z) { Node *x=NULL; Node *y=NULL; if ((z->left == NULL) || (z->right == NULL)) y = z; else y = bstree_successor(z);//找到z的後繼結點 if (y->left != NULL) x = y->left; else x = y->right; if (x != NULL) x->parent = y->parent; if (y->parent == NULL) tree = x; else if (y == y->parent->left) y->parent->left = x; else y->parent->right = x; if (y != z) z->key = y->key; if (y!=NULL) free(y); return tree; }
代碼中的bstree_successor(z)函數功能是找到結點z的後繼結點,至於什麼是後繼結點以及其實現,前文二叉搜索樹查找(請戳我)已有總結,此處再也不詳述。視頻
上面就是二叉搜索樹的插入和刪除結點的思路和代碼,你們在看代碼的時候能夠對着圖將每種狀況在本身腦中運行,好比說對於刪除操做的第一種狀況,它在代碼中的運行流程是什麼,這樣可能更加容易理解。blog
【福利】本身蒐集的網上精品課程視頻分享(上)
【數據結構與算法】 通俗易懂講解 二叉樹遍歷
【數據結構與算法】 通俗易懂講解 二叉搜索樹
【數據結構與算法】 通俗易懂講解 鏈表
【底層原理】程序局部性原理介紹
【C++札記】C/C++指針使用常見的坑it
碼農有道,爲您提供通俗易懂的技術文章,讓技術變的更簡單!