简体   繁体   English

双向链表的 Remove() 方法

[英]Remove() method for a doubly linked list

 /**
 * The remove() method removes the current node from the list. If the next node exists,
 * it becomes the current node. Otherwise the previous node becomes the current node. 
 * If neither node exists, the list becomes empty.
 * 
 * @throws Exception    If the list is empty.
 */

public void remove() throws Exception
{
    if (isEmpty())
    {
        throw exListEmpty;
    }
    Node target = current;      
    Node prevNode = target.prev;
    Node nextNode = target.next;

    // current node is at head
    if (prevNode == null)
    {
        nextNode.prev = null;
        head = nextNode;
    }
    else
    {
        prevNode.next = nextNode;
        current = prevNode;
    }

    // current node is at tail
    if (nextNode == null)
    {
        prevNode.next = null;
        tail = prevNode;
    }
    else
    {
        nextNode.prev = prevNode;
        current = nextNode;
    }
    if (prevNode == null && nextNode == null)
    {
        isEmpty();
    }
    else if (prevNode != null && nextNode != null)
    {
        prevNode.next = nextNode;
        nextNode.prev = prevNode;
        current = nextNode;
    }
    size--; 
}

The test code is:测试代码为:

    public void testContains() throws Exception
    {
        PDLinkedList first = new PDLinkedList();
        first.append(5);
        first.insert(7);
        first.add(8);

        System.out.println("Before first remove: " + first.toString());
        first.remove(); 
        System.out.println("After first remove: " + first.toString());
        first.remove(5);
        System.out.println("After second remove: " + first.toString());
        first.remove();
        System.out.println("After third remove: " + first.toString());
    }

Which then prints out as:然后打印为:

Before first remove: 7 8 5
After first remove: 7 8 5
After second remove: 7 8
After third remove: 7 8

It should remove the 8 after the first remove(), then the 7 after the third remove().它应该在第一个 remove() 之后删除 8,然后在第三个 remove() 之后删除 7。 My add(item) method is set as the current pointer, and my remove() method should then remove the node at the current pointer.我的 add(item) 方法被设置为当前指针,然后我的 remove() 方法应该删除当前指针处的节点。 But it seems to do nothing.但它似乎什么也没做。 I wonder if it is pointing at the wrong node?我想知道它是否指向错误的节点? The code compiles, but I receive an Assertion Error that states the 7 and 8 are still in the list.代码可以编译,但我收到一个断言错误,指出 7 和 8 仍在列表中。

Consider removing a node in 5 distinct cases:考虑在 5 种不同情况下删除节点:

  1. List is empty列表为空
  2. List contains only one element列表只包含一个元素
  3. Target node is in the beginning目标节点在开头
  4. Target node is in the end目标节点到底
  5. Target node is at other position目标节点在其他位置

Do no mash everything in one long function, break it into corresponding steps:不要在一个长函数中混合所有内容,将其分解为相应的步骤:

(1) Is easy, just return (1) 很简单,直接返回

(2) You make both head and last point to null (2) 将headlast指向null

(3) You assign head to head.next , and head.previous to null ( head is already "new" head) (3)分配headhead.next ,并head.previousnullhead已经是“新”的头)

void RemoveAtStart()
{
    if (IsEmpty())
    {
        return;
    }

    if (Head == Last)
    {
        Head = null;
        Last = null;
    }
    else
    {
        Head = Head.Next;
        Head.Previous = null;
    }       
}

(4) Is very similar: last becomes last.previous , and last.next to null ( last is "new" last) (4) 非常相似: last变成last.previous ,而last.next变成nulllast是“new” last)

void RemoveAtEnd()
{
    if (IsEmpty())
    {
        return;
    }

    if (Last == Head)
    {
        Last = null;
        Head = null;            
    }
    else
    {
        Last = Last.Previous;
        Last.Next = null;
    }       
}

(5) You find target , then point target.previous.next to target.next ("left" node of target skips it, and points to the right node of target). (5)你找到target ,然后点target.previous.nexttarget.next (“左”的目标节点跳过它,并指向目标的右节点)。 Then, if target is not the last, point target.Next.Previous to target.Previous .然后,如果 target 不是最后一个,将target.Next.Previous指向target.Previous

Then you combine all cases 1-5 :然后结合所有情况1-5

void Remove(Node<T> node)
{
    if (IsEmpty())
    {
        return;
    }

    if (Head == Last)
    {
        Head = null;
        Last = null;
    }
    else if (node == Last)
    {
        RemoveAtEnd();
    }
    else if (node == Head)
    {
        RemoveAtStart();
    }
    else
    {
        Node<T> current = Head;
        while (current != node)
        {
            current = current.Next;
        }
        current.Previous.Next = current.Next;
        if (current.Next != null)
        {
            current.Next.Previous = current.Previous;
        }        
        current = null;        
    }       
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM