160 lines
4.4 KiB
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;
|
|
}
|
|
|
|
}
|