-1

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?

Bart
  • 19,692
  • 7
  • 68
  • 77
Zia ur Rahman
  • 1,411
  • 4
  • 26
  • 43
  • Are you asking how to implement a set (disjoint or otherwise) as an abstract data type? Or are you asking something else entirely? – Liz Albin Feb 16 '10 at 18:46

2 Answers2

1

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

rmn
  • 2,386
  • 1
  • 14
  • 21
0
#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();
}


  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 29 '22 at 00:43