您的位置:首页 > 移动开发 > IOS开发

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;


}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息