我正在编写一些代码,我需要删除循环链接列表中的项目(谁的头部充当虚拟节点)并返回它(如果删除第一个节点)。我想我的代码恰到好处,但我不确定。
我是否理解正确? (从虚拟节点开始)
假 - > A - > B - > C - > D - >假 (环绕虚拟节点)
因此,如果我想删除第一个实际数据(A),我需要将其分配给临时变量。所以Node first = head.next。然后我需要假头参考“b”所以我需要做head.next = first.next。这一切都需要做吗?
private Node remove()
{
Node returnNode = head.next;
head.next = returnNode.next;
return returnNode;
}
如果从列表中删除任何节点N(假设它在列表中),它是一个相同的概念?所以从上面的例子中,假设我们要删除节点B.在这种情况下,我们需要设置B.next = B.previous和B.previous = B.next是否正确?或者我需要做像B.previous.next = B.next和B.next.previous = B.previous这样的事情吗?我是否需要遍历列表才能找到要删除的元素?
private void removeNode(Node n)
{
n.next = n.previous; // or n.previous.next = n.next
n.previous = n.next; // or n.next.previous = n.previous
}
答案 0 :(得分:0)
双链表意味着每个节点都与前一节点有连接。
您的示例只会切换下一个和上一个引用。你应该设置:
n.next.previous = n.previous n.previous.next = n.next
由于您有一个循环链表,因此在添加第一个元素或删除最后一个元素时应该只有特殊情况。
答案 1 :(得分:0)
在任何情况下,您都需要遍历列表以删除或添加,无论您使用的是单链表还是双链表或循环LL。
现在根据你的问题,你还没有提到它是否是一个双重LL,但我假设它是你在第二个例子中使用了node.previous。
根据我的理解,如果你有一个循环LL的节点,你不必担心这个节点是否是头,因为无论如何都可以使用这个节点访问所有节点。
现在如果我能够正确理解您的问题,那么对于您的第一个例子,
如果您需要删除节点(在本例中为A),则需要在函数参数中使用该节点。像这样......
// assuming the key exists in your LL.
private Node remove(Node nodeToBeRemoved)
{
Node returnNode = nodeToBeRemoved
while(currentNode.data = nodeToBeRemoved.data) {
returnNode = returnNode.next
}
returnNode.previous.next = returnNode.next
return returnNode;
}
同样应该是第二个例子的情况。