在二叉搜索树查找(请戳我)一文中主要介绍了二叉搜索树的查找,本文将继续介绍其插入和删除操做。二叉搜索树的插入和删除关键在于在插入和删除的过程当中如何继续保持二叉搜索树的性质。
二叉搜索树结点定义以下:算法
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
码农有道,为您提供通俗易懂的技术文章,让技术变的更简单!