@@ -20,81 +20,81 @@ using namespace std;
2020namespace ita
2121{
2222
23- // / @brief 采用树表示法实现的 用于不相交集合的数据结构(并查集)
24- // /
25- // / 使用了“路径压缩”和“按秩合并”两种技术来加速并查集的运行时间。\n
26- // / 这种方法实现的并查集的运行时间在实践上是线性的,但从理论上来说是超线性的。\n
27- // / 用于不相交集合的数据结构又称为查并集:在很多的应用中(比如图的算法中经常使用,还有哈夫曼编码等),将N个不同的元素分成一组不相交的集合。\n
28- // / 不相交集合上有两个重要的操作:<span style="color:#FF0000 ">找出给定元素所属的集合</span> 和 <span style="color:#FF0000 ">合并两个集合</span>。
29- class DisjointSetForest
30- {
31- public:
32- // / 集合中的一个元素
33- template <typename T>
34- struct DisjointSet
35- {
36- T Item; // /< 元素的值
37- int Rank; // /< 元素的秩
38- DisjointSet *Parent; // /< 元素的父元素
23+ // / @brief 采用树表示法实现的 用于不相交集合的数据结构(并查集)
24+ // /
25+ // / 使用了“路径压缩”和“按秩合并”两种技术来加速并查集的运行时间。\n
26+ // / 这种方法实现的并查集的运行时间在实践上是线性的,但从理论上来说是超线性的。\n
27+ // / 用于不相交集合的数据结构又称为查并集:在很多的应用中(比如图的算法中经常使用,还有哈夫曼编码等),将N个不同的元素分成一组不相交的集合。\n
28+ // / 不相交集合上有两个重要的操作:<span style="color:#FF0000 ">找出给定元素所属的集合</span> 和 <span style="color:#FF0000 ">合并两个集合</span>。
29+ class DisjointSetForest
30+ {
31+ public:
32+ // / 集合中的一个元素
33+ template <typename T>
34+ struct DisjointSet
35+ {
36+ T Item; // /< 元素的值
37+ int Rank; // /< 元素的秩
38+ DisjointSet *Parent; // /< 元素的父元素
3939
40- // / 创建一个结点:对应MAKE-SET操作
41- DisjointSet ( T const &item ) : Item( item ), Rank( 0 )
42- {
43- Parent = this ;
44- }
45- };
40+ // / 创建一个结点:对应MAKE-SET操作
41+ DisjointSet ( T const &item ) : Item( item ), Rank( 0 )
42+ {
43+ Parent = this ;
44+ }
45+ };
4646
47- #pragma region 查并集的3个基本操作
47+ #pragma region 查并集的3个基本操作
4848
49- // / 创建一个集合的操作:MAKE-SET
50- template <typename T>
51- static DisjointSet<T> * MakeSet ( T const &item )
52- {
53- return new DisjointSet<T>( item );
54- }
49+ // / 创建一个集合的操作:MAKE-SET
50+ template <typename T>
51+ static DisjointSet<T> * MakeSet ( T const &item )
52+ {
53+ return new DisjointSet<T>( item );
54+ }
5555
56- // / 查找所属集合的操作:FIND-SET
57- // / @remarks 使用了路径压缩
58- template <typename T>
59- static DisjointSet<T> * FindSet ( DisjointSet<T> *a_set )
60- {
61- // 路径压缩
62- if ( a_set != a_set->Parent ) // 判断本身不是代表
63- {
64- a_set->Parent = FindSet ( a_set->Parent );
65- }
66- return a_set->Parent ;
67- }
56+ // / 查找所属集合的操作:FIND-SET
57+ // / @remarks 使用了路径压缩
58+ template <typename T>
59+ static DisjointSet<T> * FindSet ( DisjointSet<T> *a_set )
60+ {
61+ // 路径压缩
62+ if ( a_set != a_set->Parent ) // 判断本身不是代表
63+ {
64+ a_set->Parent = FindSet ( a_set->Parent );
65+ }
66+ return a_set->Parent ;
67+ }
6868
69- // / 合并操作:UNION
70- // / @remarks 使用了按秩合并
71- template <typename T>
72- static void Union ( DisjointSet<T> *x, DisjointSet<T> *y )
73- {
74- _Link ( FindSet ( x ), FindSet ( y ) );
75- }
69+ // / 合并操作:UNION
70+ // / @remarks 使用了按秩合并
71+ template <typename T>
72+ static void Union ( DisjointSet<T> *x, DisjointSet<T> *y )
73+ {
74+ _Link ( FindSet ( x ), FindSet ( y ) );
75+ }
7676
77- #pragma endregion
77+ #pragma endregion
7878
79- private:
80- template <typename T>
81- static void _Link ( DisjointSet<T> *x, DisjointSet<T> *y )
82- {
83- if ( x->Rank > y->Rank )
84- {
85- y->Parent = x;
86- }
87- else
88- {
89- x->Parent = y;
90- }
79+ private:
80+ template <typename T>
81+ static void _Link ( DisjointSet<T> *x, DisjointSet<T> *y )
82+ {
83+ if ( x->Rank > y->Rank )
84+ {
85+ y->Parent = x;
86+ }
87+ else
88+ {
89+ x->Parent = y;
90+ }
9191
92- // 按秩合并
93- if ( x->Rank == y->Rank )
94- {
95- // 只有在秩相同时才会将最后的根结点的秩+1
96- ++( y->Rank );
97- }
98- }
99- };
92+ // 按秩合并
93+ if ( x->Rank == y->Rank )
94+ {
95+ // 只有在秩相同时才会将最后的根结点的秩+1
96+ ++( y->Rank );
97+ }
98+ }
99+ };
100100}
0 commit comments