zoukankan      html  css  js  c++  java
  • 整型并查集实现

    并查集概念:

    并查集是一种很有效对数据进行分类的数据结构,在一些有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");
       
    }

  • 相关阅读:
    一种Revit多专业协同方式
    现实猛于虎
    Revit2014如何隐藏保温层
    无能的愤怒
    Revit可载入族有何意义
    利用bentley view将Revit模型输出为3D PDF文档
    Revit中创建分段剖面视图
    Revit2014机电系统类型BUG
    sketchup插件管理器速图外挂SuTool
    优秀DWG看图软件尧创CAD
  • 原文地址:https://www.cnblogs.com/guojidong/p/2826665.html
Copyright © 2011-2022 走看看