【问题标题】:Java Double-Ended Queue implementation: Unable to find logic error in method addLast()Java 双端队列实现:无法在方法 addLast() 中找到逻辑错误
【发布时间】:2017-11-25 15:21:15
【问题描述】:

我的代码:

注意:readInt() 和 readString() 等函数是普林斯顿大学 algs4.jar 包的一部分。

import java.util.Iterator;
import java.util.NoSuchElementException;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Deque < Item > implements Iterable < Item > {

  private Node < Item > front;
  private Node < Item > back;
  private int numberOfItems;

  private class Node < Item > {
    Item item;
    Node < Item > next;
    Node < Item > prev;
  }

  public Deque() {
    front = null;
    back = null;
    numberOfItems = 0;
  }

  public boolean isEmpty() {
    return (numberOfItems == 0);
  }

  public int size() {
    return numberOfItems;
  }

  public void addFirst(Item item) {
    if (item == null) {
      // When a null element is entered
      throw new java.lang.NullPointerException("Item cannot be null");
    }
    Node < Item > newnode = new Node < Item > ();
    newnode.item = item;
    if (numberOfItems == 0) {
      // When there are no elements
      front = newnode;
      back = newnode;
    } else {
      // When there are >=1 elements
      newnode.prev = front;
      newnode.next = null;
      front.next = newnode;
      front = newnode;

    }
    numberOfItems++;
  }

  public void addLast(Item item) {
    if (item == null) {
      // When a null element is entered
      throw new java.lang.NullPointerException("Item cannot be null");
    }
    Node < Item > newnode = new Node < Item > ();
    newnode.item = item;
    if (numberOfItems == 0) {
      // When there are no elements
      front = newnode;
      back = newnode;
    } else {
      // When there are >=1 elements
      newnode.next = back;
      newnode.prev = null;
      back.prev = newnode;
      back = newnode;
    }
    numberOfItems++;
  }

  public Item removeFirst() {
    if (numberOfItems == 0) {
      // When the deque is empty
      throw new NoSuchElementException("No item to remove");
    }
    Item oldfirst = front.item;
    if (numberOfItems == 1) {
      front = null;
      back = null;
    } else {
      front = front.prev;
    }
    numberOfItems--;
    return oldfirst;
  }

  public Item removeLast() {
    if (numberOfItems == 0) {
      // When deque is empty
      throw new NoSuchElementException("No item to remove");
    }
    Item oldlast = back.item;
    if (numberOfItems == 1) {
      front = null;
      back = null;
    } else {
      back = back.next;
    }
    numberOfItems--;
    return oldlast;
  }

  public Iterator < Item > iterator() {
    return new ListIterator();
  }

  private class ListIterator implements Iterator < Item > {
    private Node < Item > current = front;

    public boolean hasNext() {
      return (current != null);
    }

    public void remove() {
      throw UnsupportedOperationException("remove is unsupported");
    }

    public Item next() {
      Item item = current.item;
      current = current.prev;
      return item;
    }
  }

  public static void main(String[] args) {
    Deque < String > deq = new Deque();
    String word;
    while (!StdIn.isEmpty()) {
      String cmd = StdIn.readString();
      if (cmd.equals("af")) {
        word = StdIn.readString();
        deq.addFirst(word);
      } else if (cmd.equals("al")) {
        word = StdIn.readString();
        deq.addFirst(word);
      } else if (cmd.equals("rf")) {
        deq.removeFirst();
      } else if (cmd.equals("rl")) {
        deq.removeLast();
      } else if (cmd.equals("noi")) {
        StdOut.println(deq.size());
      }
    }
  }
}

我将 Deque 实现为链接节点的集合。每个节点具有三个特征——内容、指向下一个项目的链接和指向前一个项目的链接。类变量 front 和 back 分别是第一个和最后一个元素的指针。

当我用我的测试客户端运行程序时,我发现这里的方法 addLast(Item) 将项目插入到前面而不是后面。

为什么会这样?我的逻辑有什么问题?

【问题讨论】:

  • 我猜你交换了frontback 节点的角色。您应该自始至终检查您的逻辑,因为您的所有方法中都可能存在类似的问题。

标签: java linked-list deque


【解决方案1】:

这是您的addLast 代码

  public void addLast(Item item) {
    if (item == null) {
      // When a null element is entered
      throw new java.lang.NullPointerException("Item cannot be null");
    }
    Node < Item > newnode = new Node < Item > ();
    newnode.item = item;
    if (numberOfItems == 0) {
      // When there are no elements
      front = newnode;
      back = newnode;
    } else {
      // When there are >=1 elements
      newnode.next = back;
      newnode.prev = null;
      back.prev = newnode;
      back = newnode;
    }
    numberOfItems++;
  }

请注意,当只有一个节点时,frontback 指向同一个节点。然后在后面加第二个节点的时候,把back.prev赋值给newnode,这是错误的。应该是:

back.next = newnode;
newnode.prev = back;
back = newnode;

【讨论】:

    【解决方案2】:

    这是你的代码

     public void addLast(Item item) {
        if (item == null) {
          // When a null element is entered
          throw new java.lang.NullPointerException("Item cannot be null");
        }
        Node < Item > newnode = new Node < Item > ();
        newnode.item = item;
        if (numberOfItems == 0) {
          // When there are no elements
          front = newnode;
          back = newnode;
        } else {
          // When there are >=1 elements
          //**Here is the issue**
          newnode.next = back;
          newnode.prev = null;
          back.prev = newnode;
          back = newnode;
        }
        numberOfItems++;
      }
    

    代替

     newnode.next = back;
     newnode.prev = null;
     back.prev = newnode;
     back = newnode;
    

    应该是

    back.next = newnode;
    newnode.prev=back;
    newnode.next = null;
    back = newnode
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-18
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 2013-03-10
      相关资源
      最近更新 更多