// CardLinkedList.java // Kiri Wagstaff, wkiri@cs.cornell.edu // August 1, 2001 public class CardLinkedList { private CardNode head; // Default constructor: creates an empty list public CardLinkedList() { head = null; } // length: returns the number of nodes in the list. public int length() { int count = 0; CardNode position = head; while (position != null) // the final node links to null { count++; position = position.link; // go to the next node } return count; } // add: inserts the new Card to the head of the list // by creating a new CardNode and linking it in front of head. public void add(Card newCard) { head = new CardNode(newCard, head); } // remove: removes the first Card, and returns it. // It's okay to return the card itself here, because Cards // have no mutator methods, and at any rate, we're done with it. public Card remove() { if (head != null) { Card c = head.data; head = head.link; return c; } else { System.out.println("Deleting from an empty list? Exiting!"); System.exit(1); } return null; } // inList: returns true if the Card is in the list. public boolean inList(Card target) { return (Find(target) != null); } // Find: returns the first node containing the Card. // If it's not there, returns null. // This method is private so no one else can get access // to the internal Cards of the list. private CardNode Find(Card target) { CardNode position; position = head; Card dataAtPosition; while (position != null) { dataAtPosition = position.data; if (dataAtPosition.equals(target)) return position; position = position.link; } return null; } // toString: return a nice String representation of the list. public String toString() { CardNode position = head; if (position == null) return "{}"; String result = "{ " + position.data; position = position.link; while (position != null) { result += ", " + position.data; position = position.link; } result += " }"; return result; } // This class is private, because no one else should ever // need to use it. private class CardNode { private Card data; // The stored Card private CardNode link; // The next CardNode in the list. public CardNode() { link = null; data = null; } // Create a CardNode with the specified Card inside it, // and link it to linkValue. Make a COPY of the Card. public CardNode(Card newData, CardNode linkValue) { data = new Card(newData.getValue(), newData.getSuit()); link = linkValue; } } // Now let's add some other fun stuff to make this more like an array: // addAt: insert the Card at the specified index (starting index is 0) public void addAt(Card newCard, int index) { if (index < 0) { // Invalid index System.out.println("Index must be positive."); return; } // Handle adding at 0 specially if (index == 0) { // Just use the regular add method add(newCard); return; } CardNode position = head; int count = 0; // Find the right place to insert the new Card while (position != null) { // Position is at node number "count" if (count == index-1) { // Create the new card, and make it point to position's link. CardNode temp = new CardNode(newCard, position.link); // Now make position's node link up with the new node position.link = temp; // Done! return; } else { // Keep moving down the list position = position.link; count++; } } // Uh oh - if we made it here, then the index was too big. Fail! System.out.println("Index " + index + " is too big for this list."); return; } // removeFrom: get the Card at the specified index and return it // also, delete it from the list public Card removeFrom(int index) { if (index < 0) { // Invalid index System.out.println("Index must be positive."); return null; } // Handle removing from 0 specially if (index == 0) { // Just use the regular remove method return remove(); } CardNode position = head; int count = 0; // Find the right Card while (position != null) { // Position is at node number "count" if (count == index-1) { // Make sure this isn't the last thing in the list. // If so, index is invalid. if (position.link == null) break; // Store the one we want Card temp = position.link.data; // Fix position's link to skip the one we're removing position.link = position.link.link; // Return this card return temp; } else { // Keep moving down the list position = position.link; count++; } } // Uh oh - if we made it here, then the index was too big. Fail! System.out.println("Index " + index + " is too big for this list."); return null; } public static void main(String[] args) { // Test the constructor CardLinkedList cll = new CardLinkedList(); System.out.println("New empty list: " + cll); // Test the add() method Card c = new Card(3, "hearts"); cll.add(c); System.out.println("Adding " + c + " gives " + cll); cll.add(c); System.out.println("Adding " + c + " gives " + cll); Card c2 = new Card(Card.KING, "spades"); cll.add(c2); System.out.println("Adding " + c2 + " gives " + cll); // Test the addAt() method Card c3 = new Card(Card.QUEEN, "clubs"); cll.addAt(c3, 2); System.out.println("Adding " + c3 + " at index 2 gives " + cll); cll.addAt(c3, 5); // should fail! System.out.println("Adding " + c3 + " at index 5 gives " + cll); // Test the inList() method System.out.println(c2 + (cll.inList(c2)? " IS " : " ISN'T ") + "in the list."); // Test the remove() method Card c4 = cll.remove(); System.out.println("Got the first element: " + c4 + ", now it's " + cll); // Test the removeFrom() method Card c5 = cll.removeFrom(2); System.out.println("Removing element 2 gives " + c5 + " and " + cll); cll.removeFrom(5); // should fail! System.out.println("Removing element 5 gives " + cll); } }