并查集解决在线等价类问题

#include<iostream>

using namespace std;
// 使用数组实现的并查集算法
int *equivClass;// 等价类数组
int n;//元素个数
void initialize(int numberOfElements) {
    // 用每个类的一个元素,初始化numberOfElements个类
    n = numberOfElements;
    equivClass = new int[n + 1];
    for (int e = 1; e <= n; ++e) {
        equivClass[e] = e; // 初始化等价类数组
    }
}

void unite(int classA, int classB) {
    // 合并类classA和classB
    // 假设类classA!=classB
    for (int k = 1; k <= n; ++k) { // 合并classB到classA
        if (equivClass[k] == classB)
            equivClass[k] = classA;
    }
}

int find(int theElement) {
    // 查找具有元素theElement的类
    return equivClass[theElement];
}

// 使用链表和整型指针实现的并查集算法
// 结构equivNode
struct equivNode {
    int equivClass; // 元素类别标识符
    int size; // 类中的元素个数
    int next; // 类中指向下一个元素的指针
};
equivNode *node; // 结点的数据
int n; // 元素个数
void initialize(int numberOfElements) {
    // 用每个类的第一个元素,初始化numberOfElements个类
    n = numberOfElements;
    node = new equivNode[n + 1];
    for (int e = 1; e <= n; ++e) {
        node[e].equivClass = e;
        node[e].next = 0; // 链表中没有下一个节点
        node[e].size = 1;
    }
}

void unite(int classA, int classB) {
    // 合并类classA和classB
    // 假设类classA!=classB
    // 使classA成为较小的类
    if (node[classA].size > node[classB].size)
        swap(classA, classB);
    // 改变较小类的equivClass值
    int k;
    for (k = classA; node[k].next != 0; k = node[k].next)
        node[k].equivClass = classB;
    node[k].equivClass = classB; // 链表的最后一个节点

    // 在链表classB的首元素之后插入链表classA
    // 修改新链表的大小
    node[classB].size += node[classA].size;
    node[k].next = node[classB].next;
    node[classB].next = classA;
}

int find(int theElement) {
    // 查找包含元素theElement的类
    return node[theElement].equivClass;
}
posted @ 2022-06-02 11:02  里列昂遗失的记事本  阅读(102)  评论(0编辑  收藏  举报