disjoint set (union-find set) (并查集)
2008-03-27 17:18
295 查看
ref:http://en.literateprograms.org/Disjoint_set_data_structure_(C)
The three main operations in disjoint set are:
MakeSet: Create a new partition containing a single given element.
Find: Figure out which partition a given element is in.
Union: Merge two partitions into a single partition.
The most efficient known and most commonly used is disjoint set forests
with path compression and the union rank heuristic
#include<iostream>
#include <cstdlib>
#include <cassert>
using namespace std;
//forest node
typedef struct forest_node_t ...{
void* value;
struct forest_node_t* parent;
int rank;
} forest_node;
forest_node* MakeSet(void* value);
forest_node* Find(forest_node* node);
void Union(forest_node* node1, forest_node* node2);
//find operation
forest_node* Find(forest_node* node) ...{
forest_node* temp;
/**//* Find the root */
forest_node* root = node;
while (root->parent != NULL) ...{
root = root->parent;
}
/**//* Update the parent pointers */
while (node->parent != NULL) ...{
temp = node->parent;
node->parent = temp;
node = temp;
}
return root;
}
//union operation
/**//* Given the root elements of two trees, merge the trees into one tree */
/**//*
If rank(s) ≠ rank(t), then rank(Union(s,t)) is the larger of rank(s) and rank(t),
we attach the tree with smaller rank to the root of the tree with larger rank.
If rank(s) = rank(t), then rank(Union(s,t)) = rank(s) + 1 = rank(t) + 1.
*/
void Union(forest_node* node1, forest_node* node2) ...{
if (node1->rank > node2->rank) ...{
node2->parent = node1;
} else if (node2->rank > node1->rank) ...{
node1->parent = node2;
} else ...{ /**//* they are equal */
node2->parent = node1;
node1->rank++;
}
}
//Make-Set operation
forest_node* MakeSet(void* value) ...{
forest_node* node = (forest_node*)malloc(sizeof(forest_node));
node->value = value;
node->parent = NULL;
/**//*MakeSet always produces a tree of rank 0: */
node->rank = 0;
return node;
}
int main() ...{
int i1=1, i2=2, i3=3;
forest_node *s1=MakeSet(&i1), *s2=MakeSet(&i2), *s3=MakeSet(&i3);
assert(Find(s1) == s1);
Union(s1, s2);
assert(Find(s1) == Find(s2));
assert(Find(s1) != Find(s3));
Union(s2, s3);
assert(Find(s1) == Find(s2) &&
Find(s1) == Find(s3));
return 0;
}
The three main operations in disjoint set are:
MakeSet: Create a new partition containing a single given element.
Find: Figure out which partition a given element is in.
Union: Merge two partitions into a single partition.
The most efficient known and most commonly used is disjoint set forests
with path compression and the union rank heuristic
#include<iostream>
#include <cstdlib>
#include <cassert>
using namespace std;
//forest node
typedef struct forest_node_t ...{
void* value;
struct forest_node_t* parent;
int rank;
} forest_node;
forest_node* MakeSet(void* value);
forest_node* Find(forest_node* node);
void Union(forest_node* node1, forest_node* node2);
//find operation
forest_node* Find(forest_node* node) ...{
forest_node* temp;
/**//* Find the root */
forest_node* root = node;
while (root->parent != NULL) ...{
root = root->parent;
}
/**//* Update the parent pointers */
while (node->parent != NULL) ...{
temp = node->parent;
node->parent = temp;
node = temp;
}
return root;
}
//union operation
/**//* Given the root elements of two trees, merge the trees into one tree */
/**//*
If rank(s) ≠ rank(t), then rank(Union(s,t)) is the larger of rank(s) and rank(t),
we attach the tree with smaller rank to the root of the tree with larger rank.
If rank(s) = rank(t), then rank(Union(s,t)) = rank(s) + 1 = rank(t) + 1.
*/
void Union(forest_node* node1, forest_node* node2) ...{
if (node1->rank > node2->rank) ...{
node2->parent = node1;
} else if (node2->rank > node1->rank) ...{
node1->parent = node2;
} else ...{ /**//* they are equal */
node2->parent = node1;
node1->rank++;
}
}
//Make-Set operation
forest_node* MakeSet(void* value) ...{
forest_node* node = (forest_node*)malloc(sizeof(forest_node));
node->value = value;
node->parent = NULL;
/**//*MakeSet always produces a tree of rank 0: */
node->rank = 0;
return node;
}
int main() ...{
int i1=1, i2=2, i3=3;
forest_node *s1=MakeSet(&i1), *s2=MakeSet(&i2), *s3=MakeSet(&i3);
assert(Find(s1) == s1);
Union(s1, s2);
assert(Find(s1) == Find(s2));
assert(Find(s1) != Find(s3));
Union(s2, s3);
assert(Find(s1) == Find(s2) &&
Find(s1) == Find(s3));
return 0;
}
相关文章推荐
- 并查集(union-find set or DisjointSets)
- 并查集(union-find set or DisjointSets)
- 第十四章 DSL_1_A:Disjoint Set: Union Find Tree 并查集
- 并查集 Union-Find-Set
- 数据结构 之 并查集(Disjoint Set)
- 并查集(disjoint set)的实现及应用
- 【Panoramic stitching】并查集(disjoint set)结构及源码
- 目标融合之 ——并查集(Disjoint Sets)||(Union Find Sets)
- 并查集(union-find set)与Kruskal算法
- Union-find and Disjoint Set Union
- 并查集 (Disjoint Set)
- Disjointset 并查集(按秩合并,与路径压缩)的模板
- 并查集(disjoint_set)
- 数据结构与算法分析 – Disjoint Set(并查集)
- 一、并查集 (Union-Find Set)
- 并查集(Union-Find Set)
- 编程算法 - 并查集(disjoint set) 代码(C)
- Disjoint set(并查集) data structure
- 并查集(Union-Find Set)模板
- gw_Disjoint Set (并查集) 模板及拓展应用