二叉搜索树
二叉搜索树的结点
struct Node{
int key;
Node *parent, *left, *right;
};
插入
insert以根为节点寻找z该插入的位置。设当前节点为x,如果z的键值小于x, 则将当前节点的左子节点作为下一个节点x,反之则以右节点作为下一个节点x。如此不断向叶节点搜索。在此过程中,程序将前一个节点保存在y里,用作z的候选父节点。当x抵达NIL时搜索结束,此时的y就是z的父节点了。
void insert(int k){
Node *y = NIL;
NOde *x = root;
Node *z;
z = (Node *)malloc(sizeof(Node));
z->key = k;
z->left = NIL;
z->right = NIL;
while(x != NIL){
y = x;
if(z->key < x->key){
x = x->left;
}
else{
x = x->right;
}
}
z->parent = y;
if(y == NIL){
root = z;
}
else{
if(z->key < y->key){
y->left = z;
}
else{
y->right = z;
}
}
}
搜索
find 操作要在二叉搜索树中找出含有键值k的节点x
find(x, k)
{
while(x != NIL and k != x.key)
{
if(k < x.key)
x = x.left;
else
x = x.right;
}
return x;
}
我们以根节点为起点调用 find 函数,从根向叶搜索节点。如果给定键值小于当前节点x的键值,那么搜索目标移动至左节点继续搜索,反之移动至右节点。键值不存在时返回NIL。
删除
deleteNode 函数用于从二叉搜索树T 中删除节点z
deleteNode(T, z){
if(z.left == NIL || z.right == NIL){
y = z;
else
y = getSuccessor(z);
if(y.left != NIL)
x = y.left;
else
x = y.right;
if(x != NIl)
x.parent = y.parent;
if(y.parent == NIL)
root = x;
else if (y == y.parent.left)
y.parent.left = x;
else
y.parent.right = x;
if (y != z)
z.key = y.key;
getSuccessor(x) 用于求x的后一个节点
getSuccessor(x){
if(x.right != NIL)
return getMinimum(x.right)
y = x.parent;
while(y != NIl && x == y.right)
{
x = y;
y = y.parent;
}
return y;
}
getMinimum(x) 会在以x 为根的子树中搜索并返回键值最小的节点
getMinimum(x){
while(x.left != NIL)
x = x.left;
return x;
}
通过标准库管理集合
管理元素的 STL 容器可大致分为两类。一类是有顺序的集合,称为 序列式容器 ;另一类是经过排序的容器,称为关联式容器。
序列式容器添加元素的位置与元素本身(值)无关 STL中有 vector 、list 等;
关联式容器 添加元素的位置与元素本身(值)有关STL 为用户提供了 set 、map 、multiset 、multimap 容器
关联式容器 在管理数据的过程中会自动给元素排序。虽然序列式容器也可以进行排序,但关联式容器优点在于可以随时采用二分搜索法,搜索效率极高。
- set
#include<set> 用来将STL中的set包含在程序中
set<int> s; 用于申明一个set集合s;
set 的成员函数示例:
函数 | 功能 | 复杂度 |
---|---|---|
size() | 返回set中的元素数 | O(1) |
clear() | 清空set | O(n) |
begin() | 返回指向set开头的迭代器 | O(1) |
end() | 返回指向set末尾的迭代器 | O(1) |
insert(key) | 向set中插入元素key | O(logn) |
erase(key) | 删除含有key的元素 | O(logn) |
find(key) | 搜索与key一致的元素,并返回指向该元素的迭代器。没有与key一致的元素,则返回末尾end() | O(logn) |
- map
map集合以键和值的组合为元素,每个元素拥有1个键和1个值,集合以键作为排序的标准。各元素的键唯一,不存在重复。map可以看做是一种能使用任意类型下标的的关联式容器。
#include<map>
用来将STL中的map包含在程序中
map<string, int> T;
这里是声明了一个以string为键的int型元素;
pair为STL提供的结构体模板,其第一个元素可用first访问,第二个元素可用second访问
map的成员函数示例:
函数名 | 功能 | 复杂度 |
---|---|---|
size() | 返回map中的元素数 | O(1) |
clear() | 清空map | O(n) |
begin() | 返回指向map开头的迭代器 | O(n) |
end() | 返回指向map末尾的迭代器 | O(1) |
insert((key, val)) | 向map中插入元素(key, val) | O(logn |
erase(key) | 删除含有key 的元素 | O(logn) |
find(key) | 搜索与key一致的元素,并返回指向该元素的迭代器。没有与该元素一致的元素,则返回末尾end() | O(logn) |