带链接列表的不相交集,C ++ - Cormen

时间:2014-04-20 22:25:10

标签: c++ linked-list disjoint-sets

这是我根据Cormen实现的不相交集(算法导论 - 第2版第21章)。
我在删除对象时遇到问题(" ~DisjointSet"析构函数)。
这是因为" std :: vector的寄存器设置;"可能指向相同的" MetaSet *"。

#include <vector>
#include <string>
#include <iostream>
#include <sstream>

#define WEIGHTED_UNION_HEURISTIC

class DisjointSetLinkedList
{
    class LinkedListSet
    {
        int pos;
        LinkedListSet * parent;
        LinkedListSet * next;

    public:
        LinkedListSet(int pos) :
            pos(pos),
            parent(this),
            next(NULL)
        {
        }

        LinkedListSet * getParent()
        {
            return parent;
        }

        void setParent(LinkedListSet *  node)
        {
            this->parent = (LinkedListSet *)node;
        }

        LinkedListSet * getNext()
        {
            return next;
        }

        void setNext(LinkedListSet *  node)
        {
            this->next = (LinkedListSet *)node;
        }

        int getPos()
        {
            return pos;
        }
    };

    class MetaSet
    {
    #ifdef WEIGHTED_UNION_HEURISTIC
        int size;
    #endif
        LinkedListSet * head;
        LinkedListSet * tail;

    public:
        MetaSet(LinkedListSet * head_, LinkedListSet * tail_) :
        #ifdef WEIGHTED_UNION_HEURISTIC
            size(1),
        #endif
            head(head_),
            tail(tail_)
        {
        }

    #ifdef WEIGHTED_UNION_HEURISTIC
        int getSize()
        {
            return size;
        }

        void setSize(int size_)
        {
            this->size = size_;
        }
    #endif

        LinkedListSet * getHead()
        {
            return head;
        }

        LinkedListSet * getTail()
        {
            return tail;
        }

        void setHead(LinkedListSet * head)
        {
            this->head = head;
        }

        void setTail(LinkedListSet * tail)
        {
            this->tail = tail;
        }
    };

    std::vector<MetaSet*> sets;

public:

    DisjointSetLinkedList(int size)
    {
        make_set(size);
    }

    virtual ~DisjointSet()
    {
        for(unsigned int i = 0 ; i < sets.size() ; i++)
        {
            MetaSet * meta = sets[i];
            Set * node = meta->getHead();
            while(node!=NULL)
            {
                Set * temp  = node;
                node = node->getNext();
                delete temp;
            }
            meta->setHead(NULL);
            meta->setTail(NULL);
        }

        // The error occurs here
    //  for(unsigned int i = 0 ; i < sets.size() ; i++)
    //      delete sets[i];

        sets.clear();
    }

    void union_sets(unsigned int idx_left, unsigned int idx_right)
    {
        if(idx_left >= sets.size() ||
                idx_right >= sets.size())
            return;

        MetaSet * set_left = find_set(idx_left);
        MetaSet * set_right = find_set(idx_right);

        if(set_left == set_right)
            return;

    #ifdef WEIGHTED_UNION_HEURISTIC
        if(set_left->getSize() <
            set_right->getSize())
        {
            MetaSet * temp = set_left;
            set_left = set_right;
            set_right = temp;
        }

        set_left->setSize(
                set_left->getSize() +
                set_right->getSize()
        );
    #endif

        set_left->getTail()->setNext(
                set_right->getHead());

        set_left->setTail(
                set_right->getTail());

        LinkedListSet * node = set_right->getHead();

        while(node != NULL)
        {
            sets[node->getPos()] = set_left;
            node->setParent(set_left->getHead());
            node = node->getNext();
        }
        delete set_right;
    }

    void print_list()
    {
        std::cout << "| ";
        for(unsigned int i = 0 ; i < sets.size() ; i++)
            std::cout << sets[i]->getHead()->getPos() << " | ";
        std::cout << std::endl;
    }

private:
    void make_set(int size)
    {
        for(int i = 0 ; i < size ; i++)
        {
            LinkedListSet * node = new LinkedListSet(i);
            sets.push_back(new MetaSet(node, node));
        }
    }

    MetaSet * find_set(int i)
    {
        return sets[i];
    }
};

int main()
{
    {
    DisjointSet disjoint_set(8);
    disjoint_set.print_list();

    disjoint_set.union_sets(0, 7);
    disjoint_set.print_list();
    disjoint_set.union_sets(3, 4);
    disjoint_set.print_list();
    disjoint_set.union_sets(0, 3);
    disjoint_set.print_list();
    disjoint_set.union_sets(0, 5);
    disjoint_set.print_list();
    }

    std::cout << "Objects deleted!";
}

0 个答案:

没有答案