SimpleDrawingApp/src/com/SimpleDrawingApp/list/SListNode.java

160 lines
4.4 KiB
Java

/* SListNode.java */
package com.SimpleDrawingApp.list;
/**
* An SListNode is a mutable node in an SList (singly-linked list).
**/
public class SListNode extends ListNode {
/**
* (inherited) item references the item stored in the current node.
* (inherited) myList references the List that contains this node.
* next references the next node in the SList.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
**/
protected SListNode next;
/**
* SListNode() constructor.
* @param i the item to store in the node.
* @param l the list this node is in.
* @param n the node following this node.
*/
SListNode(Object i, SList l, SListNode n) {
item = i;
myList = l;
next = n;
}
/**
* next() returns the node following this node. If this node is invalid,
* throws an exception.
*
* @return the node following this node.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public ListNode next() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("next() called on invalid node");
}
if (next == null) {
// Create an invalid node.
SListNode node = ((SList) myList).newNode(null, null);
node.myList = null;
return node;
} else {
return next;
}
}
/**
* prev() returns the node preceding this node. If this node is invalid,
* throws an exception.
*
* @param node the node whose predecessor is sought.
* @return the node preceding this node.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(this.size) time.
*/
public ListNode prev() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("prev() called on invalid node");
}
SListNode prev = ((SList) myList).head;
if (prev == this) {
// Create an invalid node.
prev = ((SList) myList).newNode(null, null);
prev.myList = null;
} else {
while (prev.next != this) {
prev = prev.next;
}
}
return prev;
}
/**
* insertAfter() inserts an item immediately following this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public void insertAfter(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("insertAfter() called on invalid node");
}
SListNode newNode = ((SList) myList).newNode(item, next);
if (next == null) {
((SList) myList).tail = newNode;
}
next = newNode;
myList.size++;
}
/**
* insertBefore() inserts an item immediately preceding this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(this.size) time.
*/
public void insertBefore(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("insertBefore() called on invalid node");
}
SListNode newNode = ((SList) myList).newNode(item, this);
if (this == ((SList) myList).head) {
((SList) myList).head = newNode;
} else {
SListNode prev = (SListNode) prev();
prev.next = newNode;
}
myList.size++;
}
/**
* remove() removes this node from its SList. If this node is invalid,
* throws an exception.
*
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(this.size) time.
*/
public void remove() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("remove() called on invalid node");
}
if (this == ((SList) myList).head) {
((SList) myList).head = next;
if (next == null) {
((SList) myList).tail = null;
}
} else {
SListNode prev = (SListNode) prev();
prev.next = next;
if (next == null) {
((SList) myList).tail = prev;
}
}
myList.size--;
// Make this node an invalid node, so it cannot be used to corrupt myList.
myList = null;
// Set other reference to null to improve garbage collection.
next = null;
}
}