二叉搜索树
二叉搜索树满足二分搜索的特性,这种类型的树类似于二分搜索在数组上进行时的形式,每次进行搜索时,其要比较的元素都会减半。

二分搜索属性
二分搜索要求,每个节点中的键必须大于或者等于存储在左子树中的键,且小于等于存储在右子树中的任何键。
- 节点的左子树仅包含键值小于当前节点键值的节点
- 节点的右子树仅包含键值大于当前节点键值的节点
- 左右子树分别时一颗二叉树
- 树中没有重复的节点
二叉搜索树的常用操作
查找
为了在树中搜索直到的键值,按照类似于二分搜索的形式进行:
- 比较给定键值和根节点的键值
- 如果相等,则找到目标值
- 如果给定值小于根节点值,则返回节点的左子树
- 如果给定值大于根节点值,则返回节点的右子树
- 递归继续搜索,直到找到元素或者遍历完成为止
插入
根据二分搜索的属性遍历相应的节点。
- 比较给定键值和根节点的键值
- 如果给定值小于根节点值,则返回节点的左子树
- 如果给定值大于根节点值,则返回节点的右子树
- 递归重复此操作,直到找到叶子节点。将其作为新节点插入到当前位置。
struct Node* InsertNode(struct Node* root,int data){
if (root==NULL)return createNode(data);
if (data<root->data){
root->left=insert(root->left,data);
}else if (data>root->data){
root->right=insert(root->right,data);
}
return root;
}
删除
在二叉搜索树中,相对于插入,删除节点是一个比较复杂的操作。为了保证删除节点之后树仍是有序的,可能需要考虑以下三种情况:
- 删除的节点没有子节点
简单的从树中移除叶子节点,不会影响树的顺序

- 删除节点的子节点
该节点被删除并用其子节点替换,在实现过程中,我们将子节点复制到要删除的节点,然后删除子节点

- 删除两个子节点的父节点
首先,我们成功查找到当前节点,然后将这个节点的有序后续节点复制到要删除的节点,保持删除之后节点任然有序。

struct Node *minValueNode(struct Node* node){
struct Node* current=node;
while(current&¤t->left!=NULL){
current=current->left;
}
return current;
}
struct Node* deleteNode(struct Node* root,int key){
if (root==NULL)return root;
if (key<root->key){
root->left=deleteNode(root->left,key);
}else if(key>root->key){
root->right=deleteNode(root->right,key);
}else{
if (root->left==NULL){
struct Node *temp=root->right;
free(root);
return temp;
}else if (root->right==NULL){
struct Node* temp=root->left;
free(root);
return temp;
}
struct Node* temp=minValueNode(root->right);
root->key=temp->key;
root->right=deleteNode(root->right,temp->key);
}
return root;
}
更多内容,欢迎访问:
