整型并查集实现

并查集概念:

并查集是一种很有效对数据进行分类的数据结构,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高,根本就不可能在比赛规定的运行时间(1~3秒)内计算出试题需要的结果,只能采用一种全新的抽象的特殊数据结构——并查集来描述。如图,就是一个并查集的结构:

 

1

 

并查集节点:

//使用数组表示,适用场合是固定大小的数组
struct Tree_node{
    int index;   //节点下标
    int parent;  //无父节点是为-1
    int value;   //节点值
    int rank;    //节点的秩
};
typedef struct Tree_node NODE;

NODE node[10]; //声明一个全局的数组

 

查找最高节点操作1:

//没有璐姐压缩的版本
int find_(NODE *n){
    int index = n->index;
    while(node[index].parent != -1){
        index = n->parent;
    }
    return index;
}

查找最高节点操作2:

//含有路径压缩的版本
int find(NODE *n){
    int final = find_(n); //先找到最终的父节点
    int index = n->index;
    while(node[index].parent != -1){
        node[index].parent = final;  //进行路径压缩
        index = node[index].parent;
    }
    return index;
}

 

并操作:

int union_(NODE *x,NODE *y){
    int final;
    int x_parent = find(x);
    int y_parent = find(y);
    if (node[x_parent].rank == node[y_parent].rank){
        node[y_parent].parent = x_parent;
        node[x_parent].rank += 1;
        final = x_parent;
    }else if(node[x_parent].rank > node[y_parent].rank){
        node[y_parent].parent = x_parent;
        final = x_parent;
    }else {
        node[x_parent].parent = y_parent;
        final = y_parent;
    }
    return final;
}

 

测试数据:

int main(){

    int i;
    int m1,m2,m0;
    m1 = m2 = m0 = 0;
    int p0[3];
    int p1[4];
    int p2[3];

    for(i=0;i<10;i++){
        node[i].index = i;
        node[i].parent = -1;
        node[i].rank = 0;
        node[i].value = i + 10;
        if(node[i].value % 3 == 0){
            p0[m0++] = i;
        }else if((node[i].value % 3 == 1)){
            p1[m1++] = i;
        }else{
            p2[m2++] = i;
        }
    }
   
    union_(&node[p0[0]],&node[p0[1]]);
    union_(&node[p0[2]],&node[p0[1]]);


    union_(&node[p1[0]],&node[p1[1]]);
    union_(&node[p1[2]],&node[p1[3]]);
    union_(&node[p1[2]],&node[p1[1]]);

    union_(&node[p2[0]],&node[p2[1]]);
    union_(&node[p2[2]],&node[p2[1]]);
   
    cout<<"ending is coming..";
    system("pause");
   
}

posted on 2012-12-20 16:53  codingcool  阅读(158)  评论(0编辑  收藏  举报