这是一个双链接列表吗? 从java背景中,下面是C++代码,我想从中理解代码列表Listp的概念用法;代码>类中的成员

这是一个双链接列表吗? 从java背景中,下面是C++代码,我想从中理解代码列表Listp的概念用法;代码>类中的成员,c++,C++,我不明白,如何将DListtype对象强制转换为DListNodetype in codenode->add((DListNode*)this,this)和this.tail=(DListNode*)this 我的目标是将这个C++代码转换成java。 class DList { private: friend class DlistNode; DListNode* head ; DListNode* dummy ; D

我不明白,如何将
DList
type对象强制转换为
DListNode
type in code
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 ) ;
        }

}


我的问题:

(一)
listp
成为
类DListNode
成员的目的是什么

(二)
类数据列表中的
tail
成员的用途是什么?

1)列表p是指向整个列表的指针。这只允许在给定节点指针的情况下对列表进行操作

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

对于双链接列表来说,这不是一个有效的(或至少不是一个很好的)实现。
DList
类正在做一些非常危险的事情,
DListNode
没有意识到,而且
DListNode
根本没有管理
DList
head
tail
成员

最安全的方法是只使用STL
std::list
类,让它为您处理所有细节。但是,如果您必须手动实现,请尝试类似的方法:

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


“我如何理解listp是类DListNode的成员?”是什么意思?而“可视化”是什么意思?祝您好运,将链表转换为Java。您知道Java中没有指针吗?你知道ArrayList和类似的东西已经内置了吗?@Yann4 Java引用足以实现各种链表。并且C++有<代码> STD::vector < /COD>和 STD::列表,但这从来没有阻止任何人实现他们自己的教育目的列表。但是我被卡住了,因为
listp
是每个节点的成员。我无法理解这里的概念用法。@delnan我同意教育目的的说法,但我指出有更简单的语言。事实上,我承认你的观点。我已经忘记了Java中的引用,已经有一段时间了。正如您所说,
listp
是指向整个列表的指针,为什么
listp
是每个DListNode的一部分?当您说,
这只允许在给定一个节点指针的情况下对列表进行操作时,我没有理解。
查看
add()
listp->size++。在没有列表指针的情况下实现这一点几乎是不可能的。我可以在DList()方法中推动添加内容,我认为这不是主要目的。我同意有其他方法来实现列表,你问过这个。listp位于节点中的原因是因为该行。如果你不想要这个功能,你可以不用指针就可以了。这是一个带有sentinel的双循环链表。哨兵的下一步指向列表的第一个节点。Sentinel的prev指向最后一个节点。Dlist的头部指向哨兵,Dlist的尾部指向最后一个节点,我的理解正确吗?为什么
DListNode
要管理
Dlist
头部和
尾部成员?我认为这是D列表的责任。对吗?
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++;
    }
};