// Stuart Reges handout #10 // 5/23/05 // // DoublyLinkedIntList provides an implementation of the IntList interface // backed by a doubly-linked list. This will provide O(1) performance for // adding at the front or back of the list and removing values while // iterating over the list. Methods like get and set will be O(n) for // values in the middle of the list. public class DoublyLinkedIntList { private ListNode front; // first value in the list private ListNode back; // last value in the list private int size; // current number of elements // post: constructs an empty list public DoublyLinkedIntList() { clear(); } // post: returns the current number of elements in the list public int size() { return size; } // pre : 0 <= index < size() // post: returns the integer at the given index in the list public int get(int index) { checkIndex(index); ListNode current = gotoIndex(index); return current.data; } // post: appends the given value to the end of the list public void add(int value) { if (front == null) { front = new ListNode(value); back = front; } else { back.next = new ListNode(value, null, back); back = back.next; } size++; } // pre: 0 <= index <= size() // post: inserts the given value at the given index, shifting subsequent // values right public void add(int index, int value) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("illegal index"); if (index == 0) addFirst(value); else if (index == size) add(value); else { ListNode current = gotoIndex(index - 1); ListNode newNode = new ListNode(value, current.next, current); current.next = newNode; newNode.next.prev = newNode; size++; } } // add value as new first element of the list private void addFirst(int value) { front = new ListNode(value, front, null); if (front.next != null) front.next.prev = front; if (back == null) back = front; size++; } // pre : 0 <= index < size() // post: removes value at the given index, shifting subsequent values left public void remove(int index) { checkIndex(index); if (index == 0) removeFirst(); else if (index == size - 1) removeLast(); else { ListNode current = gotoIndex(index - 1); current.next = current.next.next; current.next.prev = current; size--; } } private void removeFirst() { front = front.next; if (front == null) back = null; else front.prev = null; size--; } private void removeLast() { back = back.prev; if (back == null) front = null; else back.next = null; size--; } // pre : 0 <= index < size() // post: replaces the integer at the given index with the given value public void set(int index, int value) { checkIndex(index); ListNode current = gotoIndex(index); current.data = value; } // post: list is empty public void clear() { front = null; back = null; size = 0; } // pre : 0 <= index < size() // post: returns the node at a specific index. Uses the fact that the list // is doubly-linked to start from the front or the back, whichever // is closer. private ListNode gotoIndex(int index) { ListNode current; if (index < size / 2) { current = front; for (int i = 0; i < index; i++) current = current.next; } else { current = back; for (int i = size - 1; i > index; i--) current = current.prev; } return current; } // post: throws an exception if the given index is out of range private void checkIndex(int index) { if (index < 0 || index >= this.size) throw new IndexOutOfBoundsException("illegal index"); } } // ListNode is a class for storing a single node of a linked list storing // integer values. It has three public data fields for the data and the // two links to the next node and the previous node in the list and has // two constructors. public class ListNode { public int data; // data stored in this node public ListNode next; // link to next node in the list public ListNode prev; // link to previous node in the list // post: constructs a node with given data and null links public ListNode(int data) { this(data, null, null); } // post: constructs a node with given data and given links public ListNode(int data, ListNode next, ListNode prev) { this.data = data; this.next = next; this.prev = prev; } }
Stuart Reges
Last modified: Wed May 25 17:15:04 PDT 2005