簡體   English   中英

刪除/撤銷雙向鏈表中的唯一節點

[英]Removing/undoing the only node in a doubly linked list

我的代碼從最新的添加開始,一一撤消添加的元素。 除非列表中只剩下一個節點並且我的代碼沒有從列表中撤消/刪除它,否則它會正確執行所有操作。 例如:

[A, B, C, D, E] //call undo()
[A, B, C, D] //call undo()
[A, B, C] //call undo()
[A, B] //call undo()
[A] //call undo() and it throws Exception here <------------------
Exception in thread "main" java.lang.NullPointerException

如果我撤消[A]它應該返回空列表[] 注意:我必須使用一個名為beginMarkerendMarker節點,它們的值為null ,所以最后一個元素看起來像這樣:

beginMarker <-> "A" <-> endMarker

對於最后一個元素,代碼檢查大小是否等於1並且它為真並繼續進行但不會清空列表。 任何幫助,將不勝感激!

 public void add(x){
         .........
         undoStack.push(newNode);
    }
    public void undo(){
            if(undoStack.isEmpty()){
                throw new RuntimeException("Undo history is empty");
            }
            else{
                Node<T> object = undoStack.topAndPop();

                redoStack.push(object);
                if(this.size() == 1){
                    beginMarker = object.next;
                    beginMarker.next = null;
                    //beginMarker.next = null;
                }

                if(object.prev == beginMarker){
                    beginMarker.next = object.next.prev;
                    object.next.prev = beginMarker;
                }

                else if(object.next == null){
                    object.prev.next = null;
                }
                else{
                    object.next.prev = object.prev;
                    object.prev.next = object.next;
                }





                theSize--;
                modCount--;
                countUndone++;
}

SimpleStack

public class SimpleStack<AnyType>{

  // Tracks the top node of stack.
  private Node<AnyType> topOfStack;

  // Construct the stack.
  public SimpleStack( ) {
    topOfStack = null;
  }

  // Test if the stack is logically empty.
  // @return true if empty, false otherwise.
  public boolean isEmpty( ) {
    return topOfStack == null;
  }

  // Make the stack logically empty.
  public void clear( ) {
    topOfStack = null;
  }

  // Insert a new item into the stack.
  // @param x the item to insert.
  public void push( AnyType x ) {
    topOfStack = new Node<AnyType>( x, topOfStack );
  }

  // Remove the most recently inserted item from the stack.
  // @throws UnderflowException if the stack is empty.
  public void pop( ) {
    if( isEmpty( ) )
      throw new RuntimeException( "SimpleStack pop" );
    topOfStack = topOfStack.next;
  }

  // Get the most recently inserted item in the stack.
  // Does not alter the stack.
  // @return the most recently inserted item in the stack.
  // @throws UnderflowException if the stack is empty.
  public AnyType getTop( ) {
    if( isEmpty( ) )
      throw new RuntimeException( "SimpleStack empty in getTop" );
    return topOfStack.data;
  }

  // Return and remove the most recently inserted item
  // from the stack.
  // @return the most recently inserted item in the stack.
  // @throws UnderflowException if the stack is empty.
  public AnyType topAndPop( ) {
    if( isEmpty( ) )
      throw new RuntimeException( "SimpleStack empty in topAndPop" );

    AnyType topItem = topOfStack.data;
    topOfStack = topOfStack.next;
    return topItem;
  }

  // A singly linked Node which contains data and a link to another
  public class Node<T>{
    public T data;
    public Node<T> next;

    public Node(T d, Node<T> n ){
      this.data = d;
      this.next = n;
    }
  }

}

我不會對 NPE 發生在這里感到驚訝:

if(object.prev == beginMarker){
    beginMarker.next = object.next.prev; 
    //                             ^^^^ 
    //                             is it here ? object.next is null in your case
    object.next.prev = beginMarker;
}

它應該修復它以簡單地寫

if(object.prev == beginMarker && object.next != null) {
    beginMarker.next = object.next.prev;
    object.next.prev = beginMarker;
}

但是,您實際上不必特別說明 case size() == 1 一個更簡單的實現是(假設您添加一個指向列表末尾的指針):

public void undo() {
    if (undoStack.isEmpty()) {
        throw new NoSuchElementException("Undo history is empty");
    } else {
        Node<T> object = undoStack.topAndPop();
        redoStack.push(object);

        object.prev.next = object.next;
        object.next.prev = object.prev;

        theSize--;
        modCount--;
        countUndone++;
    }
}

這應該有效,因為使用endMarker會阻止您在列表中包含任何null節點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM