简体   繁体   中英

Disjoint Set ADT Implementation in C++

I have problem in implementing a disjoint set ADT in C++ due to the fact that our teacher only explained the union and find operations. I fully understand the concepts of union and find but I am still confused about how to implement them.

Could someone please give me an idea of the implementation and also explain what the interface of this data structure should look like?

You have way too many requirements, we're not here to do your homework for you.

Have a look at http://en.wikipedia.org/wiki/Disjoint-set_data_structure

#include <iostream>

template<typename T>
class Disjoint_sets
{
public:
    int FIND(int pos);
    bool in_same_set(T data_element_1, T data_element_2);
    void UNION_IF_EQUIVALENT(T data_element_1, T data_element_2);
    void UNION(T data_element_1, T data_element_2);
    Disjoint_sets(bool (*is_equivalent)(T, T));
    Disjoint_sets();
    Disjoint_sets(T* data_arr, bool (*is_equivalent)(T, T),int size);
    void insert(T data_element);
    bool is_root(int pos_number);
    int get_pos(T data_element);
    void partition();
    void print_partition();
private:
    T* data;
    int* parent_pos;
    int* number_of_children;
    int size;
    bool (*isequivalent)(T D1, T D2);
};

template<typename T>
Disjoint_sets<T>::Disjoint_sets()
{
    data = NULL;
    parent_pos = NULL;
    number_of_children = NULL;
    size = 0;
    isequivalent = NULL;
}

template<typename T>
Disjoint_sets<T>::Disjoint_sets(bool (*is_equivalent)(T, T))
{
    isequivalent = is_equivalent;
    data = NULL;
    parent_pos = NULL;
    number_of_children = NULL;
    size = 0;
}

template<typename T>
Disjoint_sets<T>::Disjoint_sets(T* data_arr, bool (*is_equivalent)(T, T), int size)
{
    data = new T[size];
    parent_pos = new int[size];
    number_of_children = new int[size];
    this->size = size;
    isequivalent = is_equivalent;
    for (int i = 0; i < size; i++)
    {
        data[i] = data_arr[i];
        parent_pos[i] = -1;
        number_of_children[i] = 0;
    }
}

template<typename T>
bool Disjoint_sets<T>::is_root(int pos)
{
    if (pos<0 && pos>size - 1)
    {
        std::cout << "Error, invalid pos supplied to is_root\n";
        return false;
    }
    if (parent_pos[pos] == -1)
    {
        return true;
    }
    else
    {
        return false;
    }
}

template <typename T>
int Disjoint_sets<T>::FIND(int pos)
{
    while (!is_root(pos))
    {
        pos = parent_pos[pos];
    }
    return pos;
}

template<typename T>
bool Disjoint_sets<T>::in_same_set(T data_element_1, T data_element_2)
{
    return FIND(get_pos(data_element_1)) == FIND(get_pos(data_element_2));
}

template<typename T>
int Disjoint_sets<T>::get_pos(T data_element)
{
    for (int i = 0; i < size; i++)
    {
        if (data[i] == data_element)
        {
            return i;
        }
    }
    std::cout << "Could not find element\n";
    return -1;
}

template <typename T>
void Disjoint_sets<T>::UNION(T data_element_1, T data_element_2)
{
    int data_parent_1_pos = FIND(get_pos(data_element_1));
    int data_parent_2_pos = FIND(get_pos(data_element_2));
    if ( data_parent_1_pos==data_parent_2_pos )
    {
        return;
    }
    if (number_of_children[data_parent_1_pos] >= number_of_children[data_parent_2_pos])
    {
        parent_pos[data_parent_2_pos] = data_parent_1_pos;
    }
    else
    {
        parent_pos[data_parent_1_pos] = data_parent_2_pos;
    }

}

template <typename T>
void Disjoint_sets<T>::UNION_IF_EQUIVALENT(T data_element_1, T data_element_2)
{
    if (FIND(get_pos(data_element_1)) == FIND(get_pos(data_element_2)))
    {
        return;
    }
    if (isequivalent(data_element_1, data_element_2))
    {
        UNION(data_element_1, data_element_2);
    }
}

template<typename T>
void Disjoint_sets<T>::partition()
{
    for (int i = 0; i < size; i++)
    {
        for (int j = i + 1; j < size; j++)
        {
            UNION_IF_EQUIVALENT(data[i], data[j]);
        }
    }
}

template <typename T>
void Disjoint_sets<T>::print_partition()
{
    for (int i = 0; i < size; i++)
    {
        if (is_root(i))
        {
            for (int j = 0; j < size; j++)
            {
                if (FIND(j) == i)
                {
                    std::cout << data[j] << " ";
                }
            }
        }
        std::cout << "\n";
    }
}

template <typename T>
bool lol(int a, int b)
{
    return a * a == b * b;
}

int main()
{
    int arr[6] = { -1,1,2,3,-3,4 };
    Disjoint_sets<int> d(arr,lol<int>, 6);
    d.partition();
    d.print_partition();
}


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM