概念
二叉搜索树(Binary Search Tree)也称作是二叉排序树,它满足以下性质(如果不为空树):
- 左子树非空则左子树上的所有值均小于根节点的值
- 右子树非空则右子树上的所有值均大于根节点的值
- 它的左右子树也分别是二叉搜索树
了解了这些特点。下面来着重说一下BST如何删除元素:
经过观察这些子树地位置关系,我们可以将所有地删除情况分为这几种:
- 删除的节点是叶子节点
- 删除的节点只有左子树(右子树)
- 删除的节点既有左子树也有右子树
分析 & 代码
用代码理解容易一些:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
struct node{
int data;
struct node * left;
struct node * right;
};
typedef node * tree;
int ins(tree &t, int key){ //这是建立BST
if(t==NULL){
t = new node;
t->data = key;
t->left = NULL;
t->right = NULL;
}
else{
if(t->data > key)
ins(t->left, key);
if(t->data < key)
ins(t->right, key);
}
}
void inorder(tree t){ //中序遍历
if(t){
inorder(t->left);
cout<<t->data<<" ";
inorder(t->right);
}
}
int del(tree &t, int key){
if(!t)
return 0;
else{
if(t->data == key){
if(t->left==NULL){ // 这是左子树为空 如果是叶子节点也会在这里处理
tree temp = t;
t = temp->right;
free(temp);
}
else if(t->right==NULL){ // 右子树为空的情况
tree temp = t;
t = temp->left;
free(temp);
} // 左右子树都存在的情况稍微麻烦一些 对于删除这样的节点为了保持BST的性质
else{ // 我们要找到这个节点右侧的最小节点 或者 左侧的最大节点 这里用的是左侧最小节点
tree temp = t->right; // 要删除的节点的右侧节点
while(temp->left){ // 一直找到最小的节点(根据BST的性质 最小节点一定会在最左侧的位置上)
temp = temp->left;
}
t->data = temp->data; //覆盖之前节点的值
del(t->right, temp->data); //还要删除掉最小的那个节点 这个节点一定是在前面的情况(是叶子节点或者只有右子树)中 所以直接递归调用
}
}
else if(t->data > key){
del(t->left, key);
}
else if(t->data < key){
del(t->right, key);
}
}
}
int main(){
tree t= NULL;
int n;
int temp;
cin>>n;
while(n--){
cin>>temp;
ins(t, temp);
}
inorder(t);
cout<<endl;
for(int i=0; i<5; i++){
cin>>temp;
del(t, temp);
inorder(t);
cout<<endl;
}
}
这是我自己的代码,有点乱,所以MOOC上浙江大学的数据结构课对BST的删除元素也做了介绍,这是根据课上的代码改动的代码:
tree findmin(tree t){ // 从当前节点出发找到最小的值
while(t->left){
t = t->left;
}
return t;
}
int deletetree(tree &t, int key){
if(!t)
return 0;
else if(key < t->data)
deletetree(t->left, key); //依然是找到删除节点
else if(key > t->data)
deletetree(t->right, key);
else{
if(t->left && t->right){ //有做右子树的情况
tree temp = findmin(t->right);
t->data = temp->data;
deletetree(t->right, temp->data);
}
else{ // 只有左子树(右子树)或者没有子树的情况
tree temp = t;
if(!temp->left)
t = t->right;
else if(!temp->right)
t = t->left;
free(temp);
}
}
}
整理的还是很简洁的,记录一下。
以上~
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/116785.html