节点,队列,排队

时间:2013-04-11 21:59:11

标签: java queue nodes deque

我正在做这个小项目,在同一个类中创建一个队列和一个去队列,同时使用我自己的Node类和一个接口。

我面临的问题是我已经完成了所有方法,但是无法使方法removeLast工作,因为在删除之后我无法让后端链接到节点之前。请帮我提一下你的建议?谢谢。

我的节点类。

public class Node<T> {

  T info;
  Node<T> next;

  public Node(T element) {
    info = element;
    next = null;
  }

  public void setInfo(T element) {
    info = element;
  }

  public T getInfo() {
    return info;
  }

  public void setNext(Node<T> next) {
    this.next = next;
  }

  public Node<T> getNext() {
    return next;
  }

}

我的界面类

public interface DequeInterface<T> {

  void addFront(T element);

  void addLast(T element);

  T removeFront();

  T removeLast();

  boolean isEmpty();

  int getSize();
}

My deque class

import java.util.NoSuchElementException;

public class Deqeue<T> implements DequeInterface {

  public Node<T> front;
  public Node<T> rear;
  int size;

  public Deqeue() {
    front = null;
    rear = null;
    size = 0;
  }

  @Override
  public T removeFront() {
    if (isEmpty()) {
      throw new NoSuchElementException();
    }
    T element = front.getInfo();
    front = front.getNext();
    size--;
    return element;
  }

  @Override
  public T removeLast() {
    if (isEmpty()) {
      throw new NoSuchElementException();
    }
    T element = rear.getInfo();
    size--;
    return element;
  }

  @Override
  public int getSize() {
    return size;
  }

  @Override
  public boolean isEmpty() {
    return rear == null;
  }

  @Override
  public void addFront(Object element) {
    Node<T> newNode = front;

    if (newNode == null) {
      rear = front;
    }
      front = new Node(element);
      front.setNext(newNode);
      size++;
  }

  @Override
  public void addLast(Object element) {
    Node<T> newNode = rear;

    if (newNode == null) {
      front = rear;
    }
      rear = new Node(element);
      newNode.setNext(rear);
      size++;

    }
  }

5 个答案:

答案 0 :(得分:2)

问题是您的列表是单链接的。不幸的是,删除单链表的最后一个节点需要遍历整个列表。一些替代方案:

答案 1 :(得分:1)

您的Node也可以引用之前的Node。这将创建一个双向链表。

public class Node<T> {

    T info;
    Node<T> next;
    Node<T> prev;

    public Node(T element) {
        info = element;
        next = null;
        prev = null;
    }


    public void setInfo(T element) {
        info = element;
    }

    public T getInfo() {
        return info;
    }

    public void setNext(Node<T> next) {
        this.next = next;
    }

    public Node<T> getNext() {
        return next;
    }

    public void setPrev(Node<T> prev) {
        this.prev = prev;
    }

    public Node<T> getPrev() {
        return prev;
    }
}

然后在Deque课程中更改您的removeFrontremoveLast方法以解释prev

public T removeFront() {
    if (isEmpty()) {
       throw new NoSuchElementException();
    }
    T element = front.getInfo();
    front = front.getNext();
    front.setPrev(null); //<<<--------------------------
    size--;
    return element;
}

@Override
public T removeLast() {
    if (isEmpty()) {
       throw new NoSuchElementException();
     }
    T element = rear.getInfo();
    rear.getPrev().setNext(null) //<<<--------------
    rear=rear.getPrev(); //<<<--------------

    size--;
    return element;
 }

当然,addFirstaddLast方法也必须更新

@Override
public void addFront(Object element) {
    Node<T> newNode = front;

    front = new Node(element);
    front.setNext(newNode);
    if (newNode == null) {
        rear = front;
    }else{
        newNode.setPrev(front);
    }
    size++;
}

@Override
public void addLast(Object element) {
    Node<T> newNode = rear;
    rear = new Node(element);
    newNode.setNext(rear);

    if (newNode == null) {
        front = rear;
    }else{
        newNode.setNext(rear);
    } 
    size++;
}

如果您不允许更改Node的代码并且只能更改removeLast()方法,那么您可以这样做:

@Override
public T removeLast() {
    if (isEmpty()) {
       throw new NoSuchElementException();
     }
    T element = rear.getInfo();
    if(rear==first){
        rear=null;
        first=null;
    }else{
        Node<T> prev = first;
        while(prev.getNext()!=rear){
            prev=prev.getNext();
        }
        rear=prev;
        prev.setNext(null);
   }
    size--;
    return element;
 }

但这需要相当低效,因为它需要从头开始遍历整个列表。

答案 2 :(得分:0)

每个节点都应该有一个指针指向上一个节点的下一个节点

答案 3 :(得分:0)

你可以使你的列表双向链接(额外的管理和错误的机会),或者你可以在每次removeLast时重复列表并将后面设置为新的最后一个(当从最后删除时更糟糕的性能,特别是在大型列表上)。 )

答案 4 :(得分:0)

最简单的方法是实现双向链表而不是链表。因此,您的节点类需要跟踪前一个元素。您需要更新添加功能以支持此功能。完成后,删除最后一个功能将如下所示:

  @Override
  public T removeLast() {
    if (isEmpty()) {
      throw new NoSuchElementException();
    }
    T element = rear.getInfo();
    size--;
    rear.getPrev().setNext(null);
    rear = rear.getPrev();
    return element;
  }