来自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)
tail
中class DList
成员的目的是什么?
答案 0 :(得分:2)
1)listp是整个列表的指针。这允许仅给出节点指针的列表上的操作。
2)tail是指向列表中最后一项的指针。这允许一些操作(如append)为O(1)而不是O(n)。
答案 1 :(得分:0)
这不是双链表的有效(或至少不是很好)实现。 DList
课程正在做一些DListNode
未发现的非常危险的事情,DListNode
没有管理DList
head
和tail
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}}