[英]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]
它應該返回空列表[]
。 注意:我必須使用一個名為beginMarker
和endMarker
節點,它們的值為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.