【问题标题】:Add(index, element) method添加(索引,元素)方法
【发布时间】:2020-02-29 16:31:36
【问题描述】:

我正在实现一个方法 add(int index, E element),它应该在列表中的指定索引处插入指定元素,并将当前位于该位置的元素和任何后续元素向右移动。有谁知道为什么我的代码在我的方法不起作用时:

        newNode.setNext(temp.getNext());
        newNode.setPrev(temp);
        newNode.getNext().setPrev(newNode);
        temp.setNext(newNode);

在方法的末尾,但只有在我有的时候才有效

        newNode.setNext(temp.getNext());
        temp.setNext(newNode);

我的代码:

public class DoubleLinkedList<E> implements IDoubleLinkedList<E> {

DLLNode head;
DLLNode tail;
int size = 0;
@Override
public void add(int index, E element) throws IndexOutOfBoundsException {
    if (index > size) {
        throw new IndexOutOfBoundsException();
    }
    if (index < 0) {
        throw new IndexOutOfBoundsException();
    }
    if (head == null) {
        head = new DLLNode(element);
        tail = head;
    }
    else if (index == 0) {
        DLLNode temp = new DLLNode(element);
        temp.setNext(head);
        head = temp;
    } else {
        DLLNode temp = head;
        for (int i = 1; i < index; i++) {
            temp = temp.getNext();
        }
        DLLNode newNode = new DLLNode(element);
        newNode.setNext(temp.getNext());
        newNode.setPrev(temp);
        newNode.getNext().setPrev(newNode);
        temp.setNext(newNode);
    }
    size ++;
}

我的双链表的节点类:

public class DLLNode<E> {
private DLLNode<E> next;
private DLLNode<E> prev;
private E element;

public DLLNode(E element){
    this.element=element;
    prev=null;
    next=null;
}
public DLLNode(E element, DLLNode prev, DLLNode next) {
    this.element=element;
    this.prev=prev;
    this.next=next;
}
public E getData(){
    return element;
}

public void setData(E element){
    this.element=element;
}

public DLLNode getPrev(){
    return prev;
}

public DLLNode getNext(){
    return next;
}

public void setPrev(DLLNode where){
    prev=where;
}

public void setNext(DLLNode where){
    next=where;
}}

【问题讨论】:

    标签: java methods linked-list doubly-linked-list


    【解决方案1】:

    我可以看到它不起作用的三个原因:

    • if (index == 0) 块中,您永远不会设置头节点的prev 值。

    • else 块中,您永远不会检查您是否在列表末尾,因此如果您在列表末尾,您将获得NullPointerException

    • if (index == 0) 块和else 块中,如果新节点是最后一个节点,则不要设置tail

    附带说明:您使用的是 raw 泛型。切勿在没有 &lt; 之后立即使用 DLLNode。基本上,将所有DLLNode 更改为DLLNode&lt;E&gt;


    这是您测试自己的代码的方法。

    将此方法添加到DLLNode:

    void verifyIntegrity() {
        if (this.prev != null && this.prev.next != this)
            throw new AssertionError("prev.next is corrupt");
        if (this.next != null && this.next.prev != this)
            throw new AssertionError("next.prev is corrupt");
    }
    

    将此方法添加到DoubleLinkedList:

    void verifyIntegrity() {
        int count = 0;
        DLLNode<E> last = this.head;
        for (DLLNode<E> node = this.head; node != null; count++, last = node, node = node.getNext())
            node.verifyIntegrity();
        if (this.tail != last)
            throw new AssertionError("tail is corrupt");
        if (this.size != count)
            throw new AssertionError("size is corrupt");
    }
    

    现在像这样测试你的代码:

    DoubleLinkedList<Integer> listHead = new DoubleLinkedList<>();
    DoubleLinkedList<Integer> listTail = new DoubleLinkedList<>();
    DoubleLinkedList<Integer> listMid = new DoubleLinkedList<>();
    listHead.verifyIntegrity();
    listTail.verifyIntegrity();
    listMid.verifyIntegrity();
    for (int i = 0; i < 10; i++) {
        listHead.add(0, i);
        listTail.add(i, i);
        listMid.add(i / 2, i);
        listHead.verifyIntegrity();
        listTail.verifyIntegrity();
        listMid.verifyIntegrity();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 1970-01-01
      相关资源
      最近更新 更多