如果我有以下节点类
class Node {
public:
Node() { next = NULL; prev = NULL; }
~Node() {}
public :
Node *next;
Node *prev;
T data;
};
如何在函数
中创建空链表LinkedList :: LinkedList()
我的链表类具有以下功能
void append(T item);
T get(int idx);
void insert(int idx, T item);
void map(T (*pf)(T item));
T remove(int index);
int size();
void unshift(T item);
答案 0 :(得分:3)
双链表通常引用列表中的第一个和(有时)最后一个元素。
Node *first, *last;
在构造函数中,只需将它们设置为NULL
即可。然后创建一个isEmpty
方法来检查这个条件,然后你就完成了。
LinkedList::LinkedList()
{
first = NULL;
last = NULL;
}
bool LinkedList::isEmpty()
{
return (first == NULL) && (last == NULL);
}
答案 1 :(得分:1)
我的解决方案(从标准前的日子开始)一直都有
带有指针的NodeBase
类,并从中派生出来
添加数据。这允许我的DLList
对象包含
一个NodeBase
,而不是必须管理指针
seperately。 NodeBase
总是有一个构造函数
通过设置两个指针,通常将它链接到无处
对此,例如:
struct NodeBase
{
NodeBase* next;
NodeBase* prec;
NodeBase()
: next(this)
, prec(this)
{
}
~NodeBase()
{
next->prec = prec;
prec->next = next;
}
};
这样做意味着没有明确的清单结束指示符( 实际列表是循环的),所以你必须跟踪你的位置 在迭代时开始,但是它做了很多其他操作 更容易。
答案 2 :(得分:0)
正如其他答案所示,有不止一种方法可以做到这一点。这是一个特别适合您的信息:虽然它不便携式C所以可能更适合组装:
struct Node {
Node *next;
Node *prev;
};
struct List {
Node *a;
Node *b;
Node *c;
List : a(tail()), b(0), c(head())
Node *head() { return (Node *)&a; }
Node *tail() { return (Node *)&b; }
};
因此,一个struct包含一个虚拟头节点(其prev
指针当然总是为0)和一个虚尾节点(其next
指针始终为0),并保存一个庞大的节点{每个列表存储{1}}个字节,它们重叠(这使得它不可移植)。重叠不是必需的,您可以在sizeof(Node*)
而不是三个Node
中放置两个List
。
这是一个有用的结构,因为它为您提供了列表中的“开始前”和“后端”节点,这意味着您可以执行所有Node*
,{节点上的{1}}和remove
根本没有引用列表头。在这方面,它就像詹姆斯的循环列表,但与他不同的是,你也可以通过查找空指针来检查结尾 - 也可以不参考头部。
文件下,“技巧我不需要玩”。