双向链表:正确删除并在列表中间添加内容?

Doubly Linked Lists: Properly deleting an adding something in the middle of a list?

Write the code fragment that appropriately deletes the node pointed to by p (data value 14) in the doubly linked list.

我想我知道如何做到这一点:

(1) 使右边的节点previous元素指向左边的节点

(2) 使左边的节点next元素指向右边的节点

(3) 使p指向NULL的节点元素删除

但是我忘记了如何在代码中编写它(已经有一段时间了)。我在想它会是这样的(我假设 node 是一个包含 int 数据的结构,node* next 和 node* previous):

node* x = p->next;
node* y = p->previous;
x->previous = y;
y->next = x;
p->previous = nullptr;
p->next = nullptr;
delete p;
x->previous = y;

写代码片段在14和16之间插入一个节点(同图):

node *x = p->next;
node y;
y->previous = x->previous;
y->next = p->next;
x->previous = y; 
p->next = y;

这样可以吗?

删码差不多就好了。但是,请注意一些事情:

  1. 您使用的命名不一致(left 应该是 previous)。
  2. 你不需要把p的字段设置为nullptr,反正你要删除它。
  3. 最后一个x->previous = y会让这个"circular"不是你想要的!

这将是一个更好的近似值:

node *x = p->next;
node *y = p->previous;
x->previous = y;
y->next = x;
delete p;

但是,这有一个警告:如果列表是单例会怎样?也就是说,您只有 p?。请注意 p->nextp->previous 都将是 NULL,因此对 xy 的赋值将会出错! (请注意,作为第一个或最后一个元素将导致相同的问题,只是在某些方面)。

第二部分代码有点问题:

  1. 首先请注意,您的代码无法编译:y 是一个变量,您要通过 y-> 取消引用它。这是一个只能对指针进行的操作[1]。这个问题实际上更深刻,因为 y 被放置在堆栈中,一旦离开范围就会被删除,因此如果您使用 &y 获取指针。
  2. y->previous = x->previous;可以简化为y->previous = p
  3. y->next = p->next;可以简化为y->next = x

通过这些更正,这将变成:

node *y = new node();
y->previous = p;
y->next = p->next;
p->next->previous = y;
p->next = y;

但是请注意,这再一次不能处理 p 指向列表末尾的情况! (p->next->previous = y 会发生什么?),所以你应该更正它。另外, p 指向列表的开头而不是结尾是否重要?你应该处理那个吗?

唯一的实际问题是动态内存问题,其余更正只是 'readability' 更正。尽管 'readability' 是个人喜好,但您应该始终尝试使代码尽可能清晰。

[1] 除非你真的在使用 operator->() 重载,我假设你没有。