10#ifndef COMMON_DISJOINT_SET_HPP
11#define COMMON_DISJOINT_SET_HPP
14#include <unordered_map>
37 std::vector<size_t> parent;
38 std::vector<size_t> count;
47 template <
typename ITERATOR>
48 explicit DisjointSet(ITERATOR start_iterator, ITERATOR end_iterator);
49 DisjointSet(
const std::initializer_list<T>& inital_list);
57 template <
typename ITERATOR>
63 const T*
Data()
const;
66 bool IsUnion(
size_t index1,
size_t index2);
70 template <
typename FUNC>
112template <
typename ITERATOR>
114 this->
Assign(start_iterator, end_iterator);
130 this->
Assign(inital_list.begin(), inital_list.end());
168 parent.reserve(size);
235 this->Resize(list.size());
237 int list_len = list.size();
240 const T* list_ptr = list.data();
243 data_ptr = data.data();
244 parent_ptr = parent.data();
245 count_ptr = count.data();
248 for (
size_t i = 0; i < list_len; ++i) {
249 data_ptr[i] = list_ptr[i];
285template <
typename ITERATOR>
290 for (
size_t i = 0; start_iterator < end_iterator; ++i, ++start_iterator) {
291 data.emplace(*start_iterator);
292 parent.emplace_back(i);
293 count.emplace_back(1);
297 data_ptr = data.data();
298 parent_ptr = parent.data();
299 count_ptr = count.data();
328 data.swap(disjoint_set.data);
329 parent.swap(disjoint_set.parent);
330 count.swap(disjoint_set.count);
415 if (index != parent_ptr[index])
416 parent_ptr[index] = this->RootIndex(parent_ptr[index]);
418 return parent_ptr[index];
444 return this->RootIndex(index1) == this->RootIndex(index2);
469 size_t index1_root = this->RootIndex(index1);
470 size_t index2_root = this->RootIndex(index2);
473 if (index1_root != index2_root) {
474 parent_ptr[index1_root] = index2_root;
475 count_ptr[index1_root] += 1;
501 return count_ptr[this->RootIndex(index)];
524 for (
int i =
int(data.size()) - 1; i >= 0; --i)
525 size += this->RootIndex(i) == i;
558template <
typename FUNC>
561 int data_len = data.size();
564 for (
size_t i = 0; i < data_len; ++i)
565 for (
size_t j = i + 1; j < data_len; ++j)
566 if (is_union(data_ptr[i], data_ptr[j]))
609 std::unordered_map<size_t, size_t> collection_index;
612 int data_len = data.size();
615 for (
int i = 0; i < data_len; ++i)
616 if (this->RootIndex(i) == i) {
617 collection_index[i] = all_collections.size();
618 all_collections.push_back(std::vector<T>({data_ptr[i]}));
622 for (
int i = 0; i < data_len; ++i)
623 if (parent_ptr[i] != i)
624 all_collections[collection_index[parent_ptr[i]]].emplace_back(data_ptr[i]);
627 return std::move(all_collections);
List< List< T > > GetAllCollections()
获取所有集合数据
DisjointSet & Assign(const std::vector< T > &list)
重新赋值并查集
DisjointSet & Resize(size_t size)
调整并查集对象的大小
DisjointSet & Reserve(size_t size)
重置并查集所对应的空间大小
DisjointSet & Clear()
清空所有数据
DisjointSet< T > & UnionAll(const FUNC &is_union)
根据提供的判断条件对并查集中所有的数据项进行两两合并
size_t Size() const
获取并查集类的数据大小
size_t CollectionSize(size_t index)
获取单个集合的大小
DisjointSet & Union(size_t index1, size_t index2)
合并两个指定索引数据项
bool IsUnion(size_t index1, size_t index2)
判断并查集中两个指定索引数据项是否在同一个集合中
size_t CollectionsSize()
获取集合的数量
DisjointSet(const DisjointSet &disjoint_set)=default
并查集类的拷贝构造函数
DisjointSet & Swap(DisjointSet< T > &disjoint_set)
交换并查集
size_t RootIndex(size_t index)
获取并查集根节点数据索引