// Helene Martin, CSE 143 // A LinkedIntList object represents an ordered list of linked nodes. // Like ArrayIntList, LinkedIntList is an implementation of the List ADT. // Final review: rearrange public class LinkedIntList { private ListNode front; // rearranges the order of a list of integers so that all of the values in // even-numbered positions appear in reverse order followed by all of the // values in odd-numbered positions in forward order. // If the list has fewer than two elements, it should be unchanged. // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -> [8, 6, 4, 2, 0, 1, 3, 5, 7, 9] // 1) are there any easy special cases? Deal with fewer than 2 elements. // 2) draw lots of pictures // here, we saw that dealing with odd indexes was easy // even indexes seemed harder because of the reversing // 3) write any easy code, leaving lots of space // write repeating code "inside out" -- figure out what one iteration is // then add a loop. Use the statements in the loop to fix bounds // here, we access current.next.next in the loop so current.next can't be null // 4) finish any tricky code left aside earlier // we went back to playing around with pictures and found we could // bring elements to the front to reverse public void rearrange() { if (front != null && front.next != null) { ListNode current = front.next; while (current != null && current.next != null) { ListNode temp = current.next; current.next = current.next.next; temp.next = front; front = temp current = current.next; } } } // Constructs an empty list. public LinkedIntList() { front = null; } // Builds a new LinkedIntList with the specified number of nodes. // Node values start at 0 and increase in value. // pre: n >= 0 public LinkedIntList(int n) { for (int i = n - 1; i >= 0; i--) { front = new ListNode(i, front); } } // Add the given value to the end of the list. public void add(int value) { if (front == null) { front = new ListNode(value); } else { // list wasn't empty; find the back // (note: this is inefficient. We could keep a reference to the last // node) ListNode current = front; while (current.next != null) { current = current.next; } current.next = new ListNode(value); } } // Adds a value at a given index. // pre: 0 <= index <= size // Throws a NullPointerException if index > size. public void add(int index, int value) { if (index == 0) { front = new ListNode(value, front); } else { ListNode current = front; for (int i = 0; i < index - 1; i++) { current = current.next; } ListNode temp = new ListNode(value, current.next); current.next = temp; // also ok: current.next = new ListNode(value, current.next); } } // Adds the given value in sorted order, duplicates allowed. // pre: list is sorted // post: list is sorted public void addSorted(int value) { if (front == null || value < front.data) { front = new ListNode(value, front); } else { ListNode current = front; while (current.next != null && current.next.data < value) { current = current.next; } // ListNode temp = new ListNode(value, current.next); // current.next = temp; current.next = new ListNode(value, current.next); } } // Sets the given index to store the given value. // pre: 0 <= index < size, throws ArrayIndexOutOfBoundsException otherwise public void set(int index, int value) { if (index < 0 || index >= size()) { throw new ArrayIndexOutOfBoundsException(); } ListNode current = front; for (int i = 0; i < index; i++) { current = current.next; } current.data = value; } // Returns the value at a given index // pre: 0 <= index < number of nodes; front != null // throws NullPointerException if index > size. public int get(int index) { ListNode current = front; for (int i = 0; i < index; i++) { current = current.next; } return current.data; } // Removes the value at the given index. // Pre: 0 <= index < size // Throws a NullPointerException if index > size. public void remove(int index) { if (index == 0) { front = front.next; } else { ListNode current = front; for (int i = 0; i < index - 1; i++) { current = current.next; } current.next = current.next.next; } } // Returns the size of this list (inefficient -- could use a size field). public int size() { ListNode current = front; int count = 0; while (current != null) { current = current.next; count++; } return count; } // True if the list is empty, false otherwise public boolean isEmpty() { return front == null; } // Returns a comma-separated String representation of this list. 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; } } // Helene Martin, CSE 143 // A ListNode represents a single node in a linked list. It stores an // integer // value and a link to the next node. private class ListNode { public int data; public ListNode next; // Creates a ListNode with the specified integer data and next node. public ListNode(int data, ListNode next) { this.data = data; this.next = next; } // Creates a terminal ListNode with the specified integer data. public ListNode(int data) { this(data, null); } // Creates a terminal ListNode with 0 as its data. public ListNode() { this(0, null); } } }