C++ 中的不相交集 ADT 实现

发布于 2024-08-21 13:24:31 字数 136 浏览 11 评论 0原文

我在 C++ 中实现不相交集 ADT 时遇到问题,因为我们的老师只解释了并集和查找操作。我完全理解 union 和 find 的概念,但我仍然对如何实现它们感到困惑。

有人可以给我一个实现的想法,并解释一下这个数据结构的接口应该是什么样子吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

为人所爱 2024-08-28 13:24:31

你的要求太多了,我们不是来帮你做作业的。

看看http://en.wikipedia.org/wiki/Disjoint-set_data_struct

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

萌吟 2024-08-28 13:24:31
#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();
}


#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();
}


~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文