从零开始手写STL库–Set的实现
Gihub链接:miniSTL
一、Set是什么
std::set 是 C++ 标准模板库(STL)中提供的有序关联容器之一。
它基于红黑树(Red-Black Tree)实现,用于存储一组唯一的元素,并按照元素的值进行排序。
也就是:按序储存不重复的值。
与它类似的是unordered_set,也是不重复,但是无序。
二、Set要包含什么函数
正常地包含:插入、删除、查找、检查空等即可
也就是:insert, erase, contains, empty, size函数
而这些都在先前的红黑树中实现过,只需要调用即可
所以本章并没有什么难点,唯一值得提示的是,引用别的文件中的class时,注意头文件的使用
之前的红黑树定义在cpp文件中,真正使用时需要拆成:
RedBlackTree.h
RedBlackTree.cpp
这两个文件,一方面保证安全,另一方面也可以避免多个文件引用时的重复编译
使用时只需要include "RedBlackTree.h"
即可
不过这里为了省事,就只定义一个.h文件,声明与实现都在里面
那么set可以直接定义为
template <typename Key>
class mySet
{
public:
mySet() : rbtree() {}
void insert(const Key &key) { rbTree.insert(key, key); }
void erase(const Key &key) { rbTree.remove(key); }
size_t size() { return rbTree.getSize(); }
bool empty() { return rbTree.empty(); }
bool contains(const Key &key) { return rbTree.at(key) != nullptr; }
private:
myRedBlackTree<Key, Key> rbtree;
};
不过要注意,实现查找功能写的是contains,但是真正的set是find函数
判断方法为
set.find(key) == set.end()
等于说明不存在,否则存在
总结
set函数本身就是红黑树的应用,并没有什么难度,需要注意其使用方法和使用场景
官方的set具有迭代器,注意其失效场景:
删除操作:删除特定元素或范围内的元素会导致迭代器失效。
清空容器:调用 clear() 会使所有迭代器失效。
销毁容器:销毁容器对象会使所有迭代器失效。
同时std::set 的迭代器是双向迭代器(Bidirectional Iterator)
可以向前(++)和向后(–)遍历集合,但不能进行随机访问
本身是红黑树的一层封装