1 / 225

Unit 5: Implementing Abstract Data Types

Unit 5: Implementing Abstract Data Types. Lesson 16: Implementing Lists, Stacks, and Queues Lesson 17: Implementing Sets and Maps Lesson 18: Implementing Trees and Priority Queues. Lesson 16: Implementing Lists, Stacks, and Queues.

zohar
Download Presentation

Unit 5: Implementing Abstract Data Types

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Unit 5: Implementing Abstract Data Types • Lesson 16: Implementing Lists, Stacks, and Queues • Lesson 17: Implementing Sets and Maps • Lesson 18: Implementing Trees and Priority Queues

  2. Lesson 16: Implementing Lists, Stacks, and Queues

  3. Lesson 16: Implementing Lists, Stacks, and Queues Objectives: • Use an array to implement an indexed list. • Use a singly linked structure to implement an indexed list. • Use an array to implement a positional list. • Use a doubly linked structure to implement a positional list. • Use arrays or linked structures to implement stacks and queues. • Understand the runtime and memory tradeoffs of array-based and link-based implementations of linear collections.

  4. Vocabulary: base address circular linked list contiguous memory current position indicator doubly linked structure dynamic memory head linked structure node null pointer offset pointer positional list private inner class prototype sentinel node singly linked structure Lesson 16: Implementing Lists, Stacks, and Queues

  5. 16.1 Interfaces, Multiple Implementations and Prototypes • The implementation of lists fall into two categories: • array-based structures • link-based structures • The link-based implementations are also of two types: • singly linked structures • doubly linked structures

  6. 16.1 Interfaces, Multiple Implementations and Prototypes • A list ADT is a linear collection of objects ordered by position. • Java’s list classes provide three types of access to the items they contain: • Indexed-based access • Object-based access • Position-based access

  7. 16.1 Interfaces, Multiple Implementations and Prototypes • Indexed-based access: • Methods such as get, set, add, and remove expect an integer index as a parameter. • This value specifies the position, counting from 0, at which the access, replacement, insertion, or removal occurs. • Object-based access: • Methods such as contains, indexOf, and remove expect an object as a parameter and search the list for the given object. • There are two versions of remove, one index-based and the other object-based.

  8. 16.1 Interfaces, Multiple Implementations and Prototypes • Position-based access: • Through the use of a list iterator, position-based methods support moving to the first, last, next, or previous item in a list. • Each of these methods establishes a current position in the list, and we can then access, replace, insert, or remove the item at this current position.

  9. 16.1 Interfaces, Multiple Implementations and Prototypes An overview of this lesson’s interfaces and implementations

  10. 16.2 The IndexedList Interface • Our first prototype consists of a subset of the index-based methods in Java's List interface plus a few others which are described in Table 16-2. • If a method's preconditions are not satisfied, it throws an exception.

  11. 16.2 The IndexedList Interface

  12. 16.2 The IndexedList Interface • An interface contains method headers, and each implementation is obliged to define all the corresponding methods. • An interface can also include comments that state the preconditions and postconditions for each method. • Following is the code for the IndexedList interface.

  13. 16.2 The IndexedList Interface // File: IndexedList.java // Interface for the indexed list prototype public interface IndexedList { public void add(int index, Object obj); // Preconditions: The list is not full and // 0 <= index <= size // Postconditions: Inserts obj at position index and // increases the size by one.

  14. 16.2 The IndexedList Interface public Object get(int index); // Preconditions: 0 <= index < size // Postconditions: Returns the object at position index. public boolean isEmpty(); // Postconditions: Returns true if the list is empty or false otherwise. public boolean isFull(); // Postconditions: Returns true if the list is full or false otherwise. public Object remove(int index); // Preconditions: 0 <= index < size // Postconditions: Removes and returns the object at position index.

  15. 16.2 The IndexedList Interface public void set(int index, Object obj); // Preconditions: 0 <= index < size // Postconditions: Replaces the object at position index with obj. public int size(); // Postconditions: Returns the number of objects in the list public String toString(); // Postconditions: Returns the concatenation of the string // representations of the items in the list. }

  16. 16.3 The Fixed-Size Array Implementation of Indexed Lists • Figure 16-1 shows an array implementation of the list (D1, D2, D3). • The array contains three data items and has two cells unoccupied. • In an array implementation of a list, it is crucial to keep track of both the list’s size (three in this case) and the array’s length (five in this case).

  17. 16.3 The Fixed-Size Array Implementation of Indexed Lists • The next code segment shows part of our FSAIndexedList class. We have completed only the constructor: // File: FSAIndexedList.java import java.io.*; // Needed for serialization public class FSAIndexedList implements IndexedList, Serializable{ private static int DEFAULT_CAPACITY = 10; // Array’s length private Object[] items; // The array of objects private int listSize; // The list size public FSAIndexedList(){ items = new Object[DEFAULT_CAPACITY]; listSize = 0; }

  18. 16.3 The Fixed-Size Array Implementation of Indexed Lists public void add(int index, Object obj){ if (isFull()) throw new RuntimeException("The list is full"); if (index < 0 || index > listSize) throw new RuntimeException ("Index = " + index + " is out of list bounds"); // Project 16-1 } public boolean isEmpty(){. . .} public boolean isFull(){. . .}

  19. 16.3 The Fixed-Size Array Implementation of Indexed Lists public Object get(int index){. . .} public Object remove(int index){. . .} public void set(int index, Object obj){. . .} public int size(){. . .} public String toString(){. . .} }

  20. 16.4 The Singly Linked Implementation of Indexed Lists • A linked structure consists of objects linked to other objects. • The fundamental building block of such a structure is called a node. • A node has two parts: • an object • references, or pointers, to other nodes • In a singly linked structure, each node contains an object and a pointer to a successor node. • The structure as a whole is accessed via a variable called the head that points to the first node.

  21. 16.4 The Singly Linked Implementation of Indexed Lists • Figure 16-2 shows a singly linked structure containing the objects D1, D2, and D3.

  22. 16.4 The Singly Linked Implementation of Indexed Lists Coding with Nodes • In Java, the nodes in a singly linked structure are instances of a Node class, which we define as follows: public class Node { public Object value; //Object stored in this node public Node next; //Reference to the next node public Node(){ value = null; next = null; } public Node(Object value, Node next){ this.value = value; this.next = next; } }

  23. 16.4 The Singly Linked Implementation of Indexed Lists Building a Linked Structure • First we build a singly linked structure containing the three strings: • Throw • The • Ball

  24. 16.4 The Singly Linked Implementation of Indexed Lists // Build a singly linked representation of the list ("Throw", "the", "ball") // Declare some Node variables Node head, node0, node1, node2; //We count from 0 as usual // Instantiate the nodes node0 = new Node(); node1 = new Node(); node2 = new Node(); // Put an object in each node and link the nodes together head = node0; node0.value = "Throw"; node0.next = node1; node1.value = "the"; node1.next = node2; node2.value = "ball";

  25. 16.4 The Singly Linked Implementation of Indexed Lists Figure 16-3 shows the result of this effort.

  26. 16.4 The Singly Linked Implementation of Indexed Lists Building the Linked List Again • We can achieve the same result more concisely as illustrated in the next code segment: // More concise code for building the list ("Throw", "the", "ball") // Declare some Node variables Node head, node0, node1, node2; // Initialize and link the nodes node2 = new Node ("ball" , null); //Warning: a node must be created node1 = new Node ("the" , node2); //before it is used in a link. node0 = new Node ("Throw", node1); head = node0;

  27. 16.4 The Singly Linked Implementation of Indexed Lists Building the Linked List for the Last Time • We can even build the list without declaring the variables node(), node1, and node2: // Most concise code for building the list // ("Throw", "the", "ball") // Declare the head variable Node head; // Initialize and link the nodes head = new Node ("ball" , null); head = new Node ("the" , head); head = new Node ("Throw", head);

  28. 16.4 The Singly Linked Implementation of Indexed Lists Traversing a Linked List • Now suppose that we know only the head of the list and are asked to print the third word. • To do this, we have to traverse the list and follow the pointers as we go. // Print the string in node 2 Node pointer; pointer = head; //Now pointing at node 0 pointer = pointer.next; //Now pointing at node 1 pointer = pointer.next; //Now pointing at node 2 System.out.println (pointer.value); //Print the string in node 2

  29. 16.4 The Singly Linked Implementation of Indexed Lists • To generalize the preceding code, we print the string in node i: // Print the string node i, i = 0, 1, 2, . . . int index, i = 2; pointer = head; //Start at the beginning of the list for (index = 0; index < i; index++) //Traverse the list pointer = pointer.next; System.out.println (pointer.value); //Print the string in node i

  30. 16.4 The Singly Linked Implementation of Indexed Lists • We illustrate the basic technique for searching a linked list by looking for the word "cat" and printing "found" or "not found" depending on the outcome: // Search a list for the word "cat" and print "found" or "not found" // depending on the outcome. Node pointer; String str; for (pointer = head; pointer != null; pointer = pointer.next){ str = (String)(pointer.value); if (str.equals("cat") break; } if (pointer == null) System.out.println ("not found"); else System.out.println ("found");

  31. 16.4 The Singly Linked Implementation of Indexed Lists Null Pointer Exceptions • A common error occurs when writing code to manipulate linked structures. It is the nullpointer exception. • This exception occurs when the code treats null as if it were an object. For instance, consider the following code fragment: Node node0; . . . node0.value = "Throw"; //This will generate a null pointer exception if //node0 does not refer to an object.

  32. 16.4 The Singly Linked Implementation of Indexed Lists • If node0 is used with the dot operator before it has been associated with an object, then a null pointer exception is thrown. • There are three ways to deal with this situation: • Use the try-catch mechanism to handle the exception immediately or at a higher level • Detect the problem before it occurs • Ignore the exception and the JVM will print an error message in the terminal window

  33. 16.4 The Singly Linked Implementation of Indexed Lists //Handling the exception immediately. Node node0; . . . try{ node0.value = "Throw"; }catch (NullPointerException e){ . . . some corrective action goes here . . . } //Handling the exception at a higher level . . . try{ . . . call a method that works with nodes and that might throw a null pointer exception . . . }catch (NullPointerException e){ . . . some corrective action goes here . . . }

  34. 16.4 The Singly Linked Implementation of Indexed Lists The SLIndexedList Class Following is an outline of the class: // File: SLIndexedList.java import java.io.*; // Needed for serialization public class SLIndexedList implements IndexedList, Serializable{ private Node head; // Pointer to first node private int listSize; // The list size private Node nodeAtIndex; // The node at index position or null if // past the end of the list. private Node nodeBefore; // The node before index position or null // if before the beginning of the list

  35. 16.4 The Singly Linked Implementation of Indexed Lists public SLIndexedList(){ head = null; listSize = 0; } public void add(int index, Object obj){} public boolean isEmpty(){ return listSize == 0; } public boolean isFull(){ return true; }

  36. 16.4 The Singly Linked Implementation of Indexed Lists public Object get(int index){. . .} public Object remove(int index){. . .} public void set(int index, Object obj){. . .} public int size(){ return listSize; } public String toString(){ String str = ""; for (Node node = head; node != null; node = node.next) str += node.value + " "; return str; }

  37. 16.4 The Singly Linked Implementation of Indexed Lists private void locateNode(int index){. . .} // ----------------- Private inner class for Node ----------------- private class Node { private Object value; //Object stored in this node private Node next; //Reference to the next node private Node(){ value = null; next = null; }

  38. 16.4 The Singly Linked Implementation of Indexed Lists private Node(Object value, Node next){ this.value = value; this.next = next; } } }

  39. 16.4 The Singly Linked Implementation of Indexed Lists The locateNode Method • To locate node i (i = 0, 1, 2, …) in a linked list, start at the head node and visit each successive node until we reach node i. • This traversal process is used in the methods get, set, add, and remove, so to save time, we write a private helper method, locateNode, to implement the process. • Figure 16-4 shows the outcome of calling locateNode(2). • If the index equals the list size, the method sets nodeBefore to the last node and nodeAtIndex to null.

  40. 16.4 The Singly Linked Implementation of Indexed Lists

  41. 16.4 The Singly Linked Implementation of Indexed Lists Code for locateNode: private void locateNode(int index){ //Obtain pointers to the node at index and its predecessor //Preconditions 0 <= index <= listSize //Postconditions nodeAtIndex points to the node at position index // or null if there is none // nodeBefore points at the predecessor or null // if there is none nodeBefore = null; nodeAtIndex = head; for (int i = 1; i < listSize && i <= index; i++){ nodeBefore = nodeAtIndex; nodeAtIndex = nodeAtIndex.next; } if (index == listSize){ nodeBefore = nodeAtIndex; nodeAtIndex = null; } }

  42. 16.4 The Singly Linked Implementation of Indexed Lists The get and set methods • The methods get and set use locateNode to access the node at a given index position. • The get method retrieves the value in the node • The set method changes the value. • Below is the code for get: public Object get(int index){ if (index < 0 || index >= listSize) throw new RuntimeException ("Index = " + index + " is out of list bounds"); locateNode(index); return nodeAtIndex.value; }

  43. 16.4 The Singly Linked Implementation of Indexed Lists The remove Method • The remove method locates an indicated node, deletes it from the linked list, and returns the value stored in the node. • A node is deleted by adjusting pointers. • To delete the first node, set the head pointer to the first node’s next pointer (Figure 16-5).

  44. 16.4 The Singly Linked Implementation of Indexed Lists

  45. 16.4 The Singly Linked Implementation of Indexed Lists • To delete any other node, locate it. Then set the predecessor’s next pointer to the deleted node’s next pointer. (Figure 16-6).

  46. 16.4 The Singly Linked Implementation of Indexed Lists

  47. 16.4 The Singly Linked Implementation of Indexed Lists public Object remove(int index){ if (index < 0 || index >= listSize) // Check precondition throw new RuntimeException ("Index = " + index + " is out of list bounds"); Object removedObj = null; if (index == 0){ // Case 1: item is first one removedObj = head.value; head = head.next; }else{ locateNode(index); nodeBefore.next = nodeAtIndex.next; removedObj = nodeAtIndex.value; } listSize--; return removedObj; } Following is the code for the remove method:

  48. 16.4 The Singly Linked Implementation of Indexed Lists The add Method • Case 1: If the index is 0, the new node becomes the first node in the list. • The new node’s next pointer is set to the old head pointer, and the head pointer is then set to the new node. Figure 16-7 shows a node with the object D2 being inserted at the beginning of a list.

  49. 16.4 The Singly Linked Implementation of Indexed Lists • Case 2: If the index is greater than 0, the new node is inserted between the node at position index - 1 and the node at position index or after the last node if the index equals the list size. • Figure 16-8 shows a node containing the object D3 being inserted at position 1 in a list.

  50. 16.4 The Singly Linked Implementation of Indexed Lists

More Related