二叉搜索树BST(工程上几乎不用,后续理论学习的基础)(没有平衡因子的约束)
- 概念
- 节点中存储的数据,左小右大
- 按中序遍历就可以得到有序序列
- 结构(如下):树头 + 具体节点树

插入操作
static BSNode *createBSNode(Element e){
BSNode *node = malloc(sizeof(BSNode));
if(node==NULL){
return NULL;
}
node->data=e;
node->left=node->right=NULL;
return node;
}
static BSNode *insertBSNode(BSNode *node,Element e){
if(!node){
return createBSNode(e);
}
if(e < node->data){
node->left=insertBSNode(node-left,e);
}else if(e > node->data){
node-right=insertBSNode(node-right,e);
}
return node; // 已经有了data值为e的节点不用再进行插入
}
void BSNode *insertBSTree(BSTree *tree,Element e){
tree->root=insertBSNode(tree->root,e);
}
删除操作
逻辑完备性:再删除完后BST树的性质不能变
度为0的点:直接删除
度为1的点:把度为1的子节点进行替换:比如要删除图中的22节点,则只需要把33->left指向8即可。直接进行替换
度为0和度为1的代码可以归纳成一个:即先判断该节点的left是否为空,若为空,则一定为度为0或度为1的节点,直接将该节点替换为该结点指向的right即可(若度为0,则right==NULL,直接替换相当于删除;若度为1,则将right以及后面所带的子串替换上来即可)
- 度为2的点:转移矛盾,把度为2的节点转化为中序遍历中该节点的前驱或者后继节点。前驱或后继节点非0即1。
找前驱节点的极右值(比当前度为2的节点小的最大值)
找后继节点的极左值(比当前度为2的节点大的最小值)
当一个度为2的节点:
- 前驱:左边节点的最大值
- 后继:右边节点的最小值
// 找前驱节点的极左值
static BSNode *maxValueBSNode(BSNode *node) {
while (node && node->right) {
node = node->right;
}
return node;
}
static BSNode* deleteBSNode(BSTree* tree, BSNode *node, Element e) {
if (node == NULL) {
return NULL;
}
if (e < node->data) {
node->left = deleteBSNode(tree, node->left, e);
} else if (e > node->data) {
node->right = deleteBSNode(tree, node->right, e);
} else {
BSNode *tmp;
if (node->left == NULL) { // 度为1或0
tmp = node->right;
free(node);
tree->count--;
return tmp;
}
if (node->right == NULL) { // 度为1
tmp = node->left;
free(node);
tree->count--;
return tmp;
}
// 此时说明待删除的节点,度为2,替换当前节点的值(后继或前驱)
// 找这个节点的左节点的最大值
// 可以通过左边的最大值/右边的最小值进行删除
// 左边最大值:替换原来度为2的节点node,并将node->中原来左边最大值的节点删除掉
// 传入的就已经是前驱节点或者后继节点了
tmp = maxValueBSNode(node->left);
node->data = tmp->data;
node->left = deleteBSNode(tree, node->left, node->data);
}
return node;
}
913

被折叠的 条评论
为什么被折叠?



