package username.lists; /** * An implementation of simple lists using linked nodes. * * @author CSC152 2006S * @author Samuel A. Rebelsky */ public class LinkedSimpleList implements SimpleList { // +------------------+------------------------------------- // | Design Decisions | // +------------------+ /* (1) We keep a link to the front and the back of the list, so that it is easier to check when we're at the back. (We could do without the link to the back, and just scan through the list, but that's less efficient. (2) When the list is empty, we set both front and back to null. (3) We rely on the built-in versions of the standard methods. That means that most methods will generate ugly values, but that we will be confident that they are "correct". */ // +--------+----------------------------------------------- // | Fields | // +--------+ Node front; Node back; // +--------------+----------------------------------------- // | Constructors | // +--------------+ /** * Build an empty list. */ public LinkedSimpleList() { this.front = null; this.back = null; } // LinkedSimpleList() // +------------------+------------------------------------- // | Standard Methods | // +------------------+ // +----------------+--------------------------------------- // | Public Methods | // +----------------+ public void add(V val) { // Make a new node, tmp, that contains val Node tmp = new Node(val); // Abnormal case: List is empty if (this.isEmpty()) { this.front = tmp; this.back = tmp; } // if the list is empty // Normal case: List is not empty else { // Make tmp the next node of back this.back.next = tmp; // Make back tmp this.back = tmp; } // if the list is not empty } // add @SuppressWarnings({"unchecked"}) public void delete(Position pos) { // Special case: Deleting the first element if (this.front == pos) { // Update our notion of front. this.front = this.front.next; // More-special case: The list is now empty if (this.front == null) { this.back = null; } } // General case else { Node tmp = ((Node) pos).next; Node pred = (Node) this.predecessor(pos); if (this.back == pos) { this.back = pred; } pred.next = tmp; } // General case: Not deleting the first element } // delete(Position pos) public Position front() { return this.front; } // front() @SuppressWarnings({"unchecked"}) public V get(Position pos) { return ((Node) pos).val; } // get(Position) public boolean isEmpty() { return this.front == null; } // isEmpty() public boolean isFirst(Position pos) { return this.front == pos; } // isFirst(Position) @SuppressWarnings({"unchecked"}) public boolean isLast(Position pos) { return this.back == pos; } // isLast(Position) public Position predecessor(Position pos) { Node pred = this.front; while (pred.next != pos) { pred = pred.next; } return pred; } // predecessor(Position) public Position rear() { return this.back; } // rear() public void removeAll() { // Set the front and the end of the list to null this.front = null; this.back = null; } // removeAll() @SuppressWarnings({"unchecked"}) public Position successor(Position pos) { return ((Node) pos).next; } // successor(Position) } // class LinkedSimpleList