// CSE 143, Winter 2009, Marty Stepp // A LinkedAnythingList object stores a list of values using // a linked list as its underlying data structure. // This version uses "generics" so that it can store any type of value, not // just integers. It also implements the same interface as ArrayAnythingList, // so that the two can be used interchangeably in client code. public class LinkedAnythingList extends AbstractAnythingList { private ListNode front; // reference to front node in list (null if empty) // Constructs a new empty list. public LinkedAnythingList() { front = null; } // Adds the given value at the given index in the list. // Precondition: 0 <= index <= size public void add(int index, E value) { if (index == 0) { // front = new ListNode(value, front); ListNode newNode = new ListNode(value, front); front = newNode; } else { ListNode current = front; for (int i = 0; i < index - 1; i++) { current = current.next; } // insert a new node right AFTER current node ListNode newNode = new ListNode(value, current.next); current.next = newNode; } } // Returns the integer value at the given index in the list. // Precondition: 0 <= index < size public E get(int index) { // traverse to the node at the given index ListNode current = front; for (int i = 0; i < index; i++) { current = current.next; } return current.data; } // Returns the index of the first occurrence of the given value in the // list, or -1 if the value is not found in the list. public int indexOf(E value) { int index = 0; ListNode current = front; while (current != null) { if (current.data == value) { return index; } index++; current = current.next; } return -1; } // Removes the element at the given index from the list. // Precondition: 0 <= index < size public void remove(int index) { if (index == 0) { // remove front element from list front = front.next; } else { // traverse to the node before the one we want to remove ListNode current = front; for (int i = 0; i < index - 1; i++) { current = current.next; } // change its next pointer to skip past the offending node current.next = current.next.next; } } // Sets the given index in the list to store the given value. // Precondition: 0 <= index < size public void set(int index, E value) { // traverse to the node at the given index ListNode current = front; for (int i = 0; i < index; i++) { current = current.next; } current.data = value; } // Returns the number of elements in the list. // (Technically this is a little silly to do in this way, because we // could just keep a size field and increment it when elements are added // and decrement it when elements are removed. But it's another example // of traversing a linked list.) public int size() { int count = 0; ListNode current = front; while (current != null) { count++; current = current.next; } return count; } // Returns a String representation of the list, such as "[42, -3, 17]". public String toString() { if (front == null) { return "[]"; } else { String result = "[" + front.data; ListNode current = front.next; while (current != null) { result += ", " + current.data; current = current.next; } result += "]"; return result; } } // ListNode is a class for storing a single node of a linked list. This // node class is for a list of integer values. // This version has the ListNode as an inner class, so that we don't // need a separate file for it, and it can't be used outside of this file. private class ListNode { public E data; // data stored in this node public ListNode next; // link to next node in the list // post: constructs a node with given data and null link public ListNode(E data) { this(data, null); } // post: constructs a node with given data and given link public ListNode(E data, ListNode next) { this.data = data; this.next = next; } } }