我无法理解代表链表结构的C代码。结构的骨架如下所示:
struct r{
r *next;
r **prev;
data *d;
}
struct r *rlist;
可以通过调用以下函数来填充rlist :(仅限骨架)
r* rcreate(data *d){
struct r *a = xmalloc(sizeof(*r))
a->d = d;
a->next = rlist;
a->prev = &rlist;
if (rlist)
rlist->prev = &a->next;
rlist = a;
return a;
}
如何使用此数据结构?例如如何遍历rlist?
编辑:这是删除链表中节点的功能
void rdestroy(struct r *a){
if (a->next){
a->next->prev = a->prev;
}
*a->prev = a->next;
destroy(a->d); /* destroy is defined elsewhere */
}
答案 0 :(得分:1)
没有充分的理由在该结构中使用r **。这是双链表。 因此,如果创建了这个东西,则将其分配
thisList = rcreate(“我的数据”)
现在你可以开始遍历它了 while(thisList-> next) thisList = thisList-> next。 ...
答案 1 :(得分:1)
双prev
指针似乎只允许在一个方向上遍历列表,同时允许轻松删除(因为即使您无法轻松访问前一个元素),也可以访问next
指针of previous element,并在删除节点时将其设置为新的正确值。
在没有看到其他相关功能的情况下,很难理解为什么这样做。我没有看到这样做,也不能立即想到任何真正有用的好处。
我认为这允许更简单的节点删除代码,因为节点不需要关心它是否是第一个,因为节点的prev
指针对于在删除时需要修改的指针总是具有非NULL值本身。在当前节点之前插入的简单性相同。如果这些操作主导了使用模式,那么我认为这可能被视为次要优化,特别是在分支可能更昂贵的旧CPU中。
这是个问题,对吗?你只能以一种非常简单的方式向前遍历它,这里是遍历整个列表的for循环:
struct r *node;
for (node = rlist ; node ; node = node->next) {
// assert that prev points to pointer, which should point to this node
assert(*(node->prev) == node);
// use node
printf("node at %p with data at %p\n", node, node->d);
}
此示例插入函数演示了节点之前的插入如何不需要分支(未经测试):
struct r *rinsert(struct r *nextnode, data *d) {
// create and initialize new node
struct r *newnode = xmalloc(sizeof(struct r));
newnode->d = d;
newnode->next = nextnode;
newnode->prev = nextnode->prev;
// set next pointer of preceding node (or rlist) to point to newnode
*(newnode->prev) = newnode;
// set prev pointer of nextnode to point to next pointer of newnode
nextnode->prev = &(newnode->next);
return newnode;
}
答案 2 :(得分:0)
你的代码中有很多语法错误,可能是因为(如你所说)它是一个“骨架”,因此很难解析作者(无论是你或其他人)实际上是想要这个代码做什么的
简单(双重)链表结构如下所示:
struct node {
struct node *next, *prev; // pointers to the adjacent list entries
int data; // use whatever datatype you want
};
struct node *list = NULL; // the list starts empty
void add_entry(int new_data) {
struct node *new_entry = malloc(sizeof(struct node));
// note that in the above line you need sizeof the whole struct, not a pointer
new_entry->data = new_data;
new_entry->next = list; // will be added to the beginning of the list
new_entry->prev = NULL; // no entries currently front of this one
// in general a NULL pointer denotes an end (front or back) of the list
list->prev = new_entry;
list = new_entry; // now list points to this entry
// also, this entry's "next" pointer points to what used to
// be the start of the list
}
编辑:我会说,如果您希望我们帮助您了解一些较大程序的代码,您没有编写且无法修改,请以相应的格式发布相关代码至少是语法上的。正如其他人所说,例如,在您发布的代码中使用prev
是难以理解的,并且不清楚(因为还有其他类似的令人困惑的语法问题)是否在原始代码中或是否是转录中引入的错误。
答案 3 :(得分:0)
杨,我不确定你的指针是多么的舒服。我建议看看其他一些链接列表实现,它可能就是这样做的。