这是一个双重链表吗?

时间:2014-10-04 19:04:21

标签: c++

来自Java背景,下面是C ++代码,我想从中了解DList listp;类中DListNode成员的概念用法。

我无法理解,如何将DList类型对象转换为代码DListNode中的node->add ( (DListNode*) this, this ) ;类型和this.tail = (DListNode*) this ;

我的目标是将此C ++代码转换为Java。

class  DList
{
    private:
        friend class DlistNode;

        DListNode* head ;
        DListNode* dummy ;
        DListNode* tail ;
        int size;
    public:
        DList ( void ): dummy( NULL), size( 0 )
        {
            this.head = (DlistNode*) &dummy ; //this is sentinel
            this.tail = (DListNode*) this ;
        }
        void add_head   ( DListNode* node )
        {
            node->add ( (DListNode*) this, this ) ;
        }

        void add_tail ( DListNode* node )
        {
            node->add ( tail, this ) ;
        }

}

class DListNode
{
    private:

        friend class DList;

        DListNode* next ;
        DListNode* prev ;
        DList* listp;

    public:
        DListNode*  rem ( void )
        {

            if (listp)
            {
                next -> prev = prev ;
                prev -> next = next ;
                next = prev = this ;

                listp->size--;
                listp = NULL;
            }

            return ( this ) ;

        } 

        void  add ( DListNode* predecessor, DList *parent )
        {

            rem() ;

            if (!parent)
            {       
                listp = predecessor->listp;
            }
            else
            {
                listp = parent;
            }

            prev = predecessor ;
            next = prev -> next ;
            prev -> next = next -> prev = this ;

            if ( 0 != listp )
            {  
                listp->size++;
            }

        } 

}

我的问题:

1) listp成为class DListNode成员的目的是什么?

2) tailclass DList成员的目的是什么?

2 个答案:

答案 0 :(得分:2)

1)listp是整个列表的指针。这允许仅给出节点指针的列表上的操作。

2)tail是指向列表中最后一项的指针。这允许一些操作(如append)为O(1)而不是O(n)。

答案 1 :(得分:0)

这不是双链表的有效(或至少不是很好)实现。 DList课程正在做一些DListNode未发现的非常危险的事情,DListNode没有管理DList headtail std::list成员。

最安全的方法是使用STL class DList { private: friend class DlistNode; DListNode* head; DListNode* tail; int size; public: DList() : head(NULL), tail(NULL), size(0) { } ~DList() { while (head) delete head; } void add_head(DListNode* node) { node->add_head(this); } void add_tail(DListNode* node) { node->add_tail(this); } }; 类,让它为您处理所有细节。但如果您必须手动实现它,请尝试更类似的东西:

class DListNode
{
private:
    friend class DList;

    DListNode* next;
    DListNode* prev;
    DList* listp;

public:
    DListNode() : next(NULL), prev(NULL), listp(NULL)
    {
    }

    ~DListNode()
    {
        remove();
    }

    void remove()
    {
        if (next)
            next->prev = prev;

        if (prev)
            prev->next = next;

        if (listp)
        {
            if (listp->head == this)
                listp->head = next;

            if (listp->tail == this)
                listp->tail = prev;

            listp->size--;
            listp = NULL;
        }

        prev = next = NULL;
    } 

    void add_head(DList *parent)
    {
        if (!parent)
            throw std::runtime_error("no parent specified");

        if (parent->head == this)
            return;

        remove();

        if (parent->head)
        {
            parent->head->prev = this;
            next = parent->head;
        }
        parent->head = this;            

        listp = parent;
        listp->size++;
    } 

    void add_tail(DList *parent)
    {
        if (!parent)
            throw std::runtime_error("no parent specified");

        if (parent->tail == this)
            return;

        remove();

        if (parent->tail)
        {
            parent->tail->next = this;
            prev = parent->tail;
        }
        parent->tail = this;            

        listp = parent;
        listp->size++;
    } 

    void add_before(DListNode *node)
    {
        if (!node)
            throw std::runtime_error("no node specified");

        if (node == this)
            return;

        remove();

        if (node->prev)
            node->prev->next = this;

        next = node;
        prev = node->prev;
        node->prev = this;

        listp = node->listp;
        if (listp->head == node)
            listp->head = this;

        listp->size++;
    }

    void add_after(DListNode *node)
    {
        if (!node)
            throw std::runtime_error("no node specified");

        if (node == this)
            return;

        remove();

        if (node->next)
            node->next->prev = this;

        prev = node;
        next = node->next;
        node->next = this;

        listp = node->listp;
        if (listp->tail == node)
            listp->tail = this;

        listp->size++;
    }
};

{{1}}