我使用插入方法进行双向链接列表设置。 使用这个结构:
struct NODE
{
struct NODE *fwd;
struct NODE *bwd;
int value;
};
typedef struct NODE Node;
这个初始化:
void initializeList(Node *rt)
{
rt->fwd = NULL;
rt->bwd = NULL;
rt->value = 0;
}
我的主要功能是:
main()
{
Node root;
int j;
initializeList(&root);
for (j = 0; j < 15; j++)
insertFirst(&root, j);
printf("The list traversed forward \n");
traverseForward(root);
printf("\n");
printf("The list traversed backward \n");
traverseBackward(root);
printf("\n");
printf("After first deletion traverse forward\n");
deleteFirst(&root);
traverseForward(root);
printf("\n");
printf("After first deletion traverse backwards\n");
printf("\n");
traverseBackward(root);
}
我的deletefirst功能是:
void deleteFirst(Node *rt)
{
Node *newnode = rt;
Node *tmp = NULL;
if (newnode != NULL)
{
if (newnode->fwd != NULL)
{
newnode = newnode->fwd;
tmp = newnode->bwd;
*rt = *newnode;
}
else
tmp = newnode;
}
free(tmp);
}
插入功能:
int insertFirst(Node *rt, int val)
{
Node *node = (Node *)malloc(sizeof(Node));
if (node == NULL) return 0;
node->value = val;
/* For a previously empty list */
if (rt->fwd == NULL)
{
rt->fwd = node;
rt->bwd = node;
node->fwd = NULL;
node->bwd = NULL;
}
/* For a list with at least one node */
else
{
/* previous first node now new node's successor */
rt->fwd->bwd = node;
node->fwd = rt->fwd;
/* no predecessor to the new first node */
node->bwd = NULL;
/* root points to this new first */
rt->fwd = node;
}
return 1;
}
遍历功能:
void traverseForward(Node root)
{
Node *q = root.fwd;
while (q)
{
printf("%d ", q->value);
q = q->fwd;
}
}
void traverseBackward(Node root)
{
Node *q = root.bwd;
while (q)
{
printf("%d ", q->value);
q = q->bwd;
}
}
系统打印出前进的列表
14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
系统打印出向后遍历的列表
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
首次删除前向遍历后
13 12 11 10 9 8 7 6 5 4 3 2 1 0
首次删除后向遍历
(没有打印)
我无法弄清楚如何调整指针以使其发挥作用。
答案 0 :(得分:1)
我认为这个问题是因为您将头部和尾部指针存储在根节点中的列表的开头和结尾,然后将其与列表的实际节点交替混合。如果您只有简单的Node *head
和Node *tail
指针,这种混淆可能会被消除,但这只是一个建议。
在你的删除功能中,你将根节点设置为有效rt->fwd
,这对于前向遍历很好,因为rt->fwd->fwd
是你想要的,但你忘了考虑{{1}的值总是指向列表中第一项的NULL(因为在此节点之前没有任何技术),而不是列表的实际尾部,这是该逻辑所需的功能。
当您尝试使用它向后迭代时,这显然会导致问题,因为它认为列表为空。您应该将删除代码更改为以下内容:
rt->fwd->bwd
这里有很多关于边缘情况和评论提到的事情的其他问题(只是整体设计使这个问题很严重)但我认为这是你目前遇到的问题。