java programming: from the ground up chapter 16 data structures and generics

105
Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Upload: conrad-cooper

Post on 03-Jan-2016

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Java Programming:From the Ground Up

Chapter 16Data Structures and Generics

Page 2: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Data Structures

A data structure is a collection of data together with a well-defined set of operations for storing, retrieving, managing,

and manipulating the data.

Page 3: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Data Structures

Some elementary data structures: ArrayList Stack Queue Linked List

Page 4: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList

An array holds an indexed contiguous collection of data of a

single type.

Once an array is instantiated and its size declared, the size

cannot be altered.

Dynamic arrays, which grow as needed, would offer a

convenience not provided by ordinary arrays.

Page 5: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList

An ArrayList object is an indexed list of references that can

grow as the number of data increases.

An ArrayList can resize itself

Page 6: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList

Unlike an ordinary array, an ArrayList does not hold primitive values.

An ArrayList stores references and only references.

Primitive data can be automatically wrapped in objects and subsequently stored in an ArrayList.

Page 7: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList Methods

void add(int index, Object o)

inserts o at position index. If an element, x, is currently stored at position index, then x and all the elements following x are shifted “down” one position to make room for o, i.e., x is moved to position index+1 and all elements following x are also moved down one position.

Page 8: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList Methods

boolean add(Object o)

adds o to the end of the list. The boolean return value isnecessary because ArrayList implements Java’s Collection interface. For our purposes, wecan ignore the return

value.

Page 9: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList Methods

void clear()removes all objects from the list.

boolean contains (Object o)returns true if o is a member of the list.

Object get(int index)returns the Object reference at position index.

boolean isEmpty() returns true if the list has no elements.

Page 10: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList Methods

boolean remove (Object o)

If o is a member of the list, this method removes the first occurrence of o from the list, returns true, and shifts all elements following o “up” one position, i.e., if x follows o and x is stored in position i then x is moved from position i to position i – 1.

Object remove (int index)removes and returns a reference to the object o that is currently at position index;

shifts allelements following o up one position.

Page 11: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList Methods

Object set (int index, Object o)replaces the object at position index with o; returns a reference to the object that was replaced.

int size()returns the number of objects currently in the list.

Object [] toArray()returns the objects of a list as an array reference.

Page 12: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList Constructors

public ArrayList(); instantiates an ArrayList that is empty and sets the initial

capacity to 10.

public ArrayList(int initialSize); instantiates an ArrayList that

is empty and sets the initial capacity to initialSize.

Page 13: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList

An ArrayList can store Object references.

The following list (anything)

ArrayList anything = new ArrayList()

can hold references to Integers, Strings, Circles, Airplanes,any Object.

However in many applications, an ArrayList is intended to holda single type of reference. Java provides generics for this

purpose.

Page 14: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Generics

A generic class is one that allows you to specify the data

type of one or more fields as a parameter.

Page 15: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

The following segment declares and instantiates three different ArrayList objects each capable of holding references to one and only one type of object.

ArrayList<Student> students = new ArrayList<Student>();

ArrayList<String> strings = new ArrayList<String>(50);

ArrayList<Integer> numbers = new ArrayList<Integer>();

Page 16: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

Example

The Student class encapsulates a student. A Student object holds

a student’s name his/her ID number.

The Student class has getter and setter methods.

Student overrides the equals(Object o) method inherited from Object so that two students are equal if they have the same name and ID number.

Page 17: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

1. public class Student2. {3. private String name;4. private String id;5. public Student()6. {7. name = "";8. id = "";9. }10. public Student (String n, String idNum)11. {12. name = n;13. id = idNum;14. }15. public String getName()16. {17. return name;18. }19. public String getID()20. {21. return id;22. }

Page 18: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

23. public void setName(String n)24. {25. name = n;26. }27. public void setID( String idNum)28. {29. id = idNum;30. }31. public boolean equals(Object o) // name and id are the same32. {33. return ( (((Student)o).name).equals(name) &&34. (((Student)o).id).equals(id) );35. }36. }

Page 19: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

Example

An Elementary School holds a “Principal for a Day” lottery.

A student can participate by entering his/her name and ID number into a pool of candidates. The winner is selected randomly from all entries.

Each student is allowed one entry.

Page 20: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

Problem Statement

Implement a class, StudentLottery, with methods that

enter students in the “Principal for a Day” lottery, and pick a winner from the entries.

The application should check that no student enters the lottery more than once.

Page 21: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

Solution

The StudentLottery class uses an ArrayList, entries, to hold Student references.

The class has methods: void addStudents() that enters students in the lottery and void pickWinner().

pickWinner() uses the Random class to select one winner from among all student entries.

addStudents() checks that there are no duplicate entries.

When all students are entered, the name of the winning student and his/her ID are displayed.

Page 22: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

1. import java.util.*;2. public class SchoolLottery3. {4. private ArrayList<Student> entries;// holds Student references5. public SchoolLottery()6. {7. entries = new ArrayList<Student>(250); // initial capacity is 2508. }

Page 23: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

9. public void addStudents()10. {11. // prompts for student names and ID numbers12. // adds students to entries list13. // does not allow duplicate entries14. Scanner input = new Scanner(System.in);15. System.out.println("Press Enter to end input");16. System.out.print("Name: ");17. String name = input.nextLine();

Page 24: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

18. do19. {20. System.out.print("ID: ");21. String id = input.nextLine();22. Student student = new Student(name, id);23. if (!entries.contains(student)) //only one entry per student24. {25. entries.add(student);26. System.out.println(name + " entered in the lottery.");27. }28. else29. System.out.println(name + " not entered.");30. System.out.print("\nName: ");31. name = input.nextLine();32. } while (! name.equals(""));// signals end of data33. pickWinner();34. }

Page 25: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ArrayList and Generics

35. public void pickWinner()36. {37. // chooses a random entry and displays winners name and ID38. int numEntries = entries.size();// size of ArrayList39. Random random = new Random();40. Student winner = entries.get(random.nextInt(numEntries));41. System.out.print("The winner and Principal for a Day is ");42. System.out.println (winner.getName()); 43. System.out.println (winner.getID());44. }

45. public static void main(String[] args)46. {47. SchoolLottery lottery = new SchoolLottery();48. lottery.addStudents();49. }50. }

Page 26: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

More About Generics

A generic class has the formClassName <E1,E2,…En>

where Ei are type parameters.

Each Ei is a stand-in or placeholder for some reference type. That is, the arguments supplied in place of each Ei cannot

be primitive types.

Page 27: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Generics:restrictions

Restrictions: Java does not allow generic arrays. The statement

E[] myArray = new E[size]; // illegal

attempts to create an array called myArray that holds elements of type E. This is illegal; instead, use an explicit cast, such as

E[] myArray = (E[]) new Object[size]; // legal

The Java compiler will issue a warning to the effect that the cast may be unsafe. Because of the way that Java implements generics, the compiler has no way of knowing whether or not this type of cast is safe. Consequently, the compiler generates a warning message.

Page 28: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Generics:restrictions

Java does not permit instantiation of a generic type. For example, the method public illegalMethod (E t) { E copy = new E(); // illegal // other statements }

generates a compilation error.

Page 29: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Generics, Inheritance, and Polymorphism

The use of inheritance in combination with generics naturally imposes a helpful limitation on the kinds of types allowed.

The class declaration

public className <T extends P>

restricts type parameter T to the class P and its subclasses.

Page 30: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Generics, Inheritance, and Polymorphism

1. public class Average<T extends Number > // does not compile2. {3. private T[] list;4. public Average(T[] l)5. {6. list = l;7. }8. public double findAverage()9. {10. double sum = 0.0;11. for(int i = 0; i < list.length; i++)12. sum = sum+ list[i].doubleValue()13. return sum/list.length;14. }

The type parameter T is intended to be a numeric type such as Integer, Double, Float, Byte, Short, or Long.

Page 31: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack

A stack is a ordered list of data such that items can be added to and removed from just one end of the list, the top of the stack.

Access to a stack is more restrictive than access to an ArrayList.

When you add an item to the top of the stack you push the item onto thestack.

When you remove the top item from a stack, you pop the stack.

Page 32: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack

If s is a stack of strings that is initially empty, the operations push “Hamlet”, push “Rosencranz”, and push “Guildenstern”

place the three strings on s.

Because “Guildenstern” is the last string pushed onto s,“Guildenstern” occupies the top position.

Page 33: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack

A stack after three push operations

Page 34: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack

Two pop operations, remove the top two

strings from s.

Page 35: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Implementation

The standard stack operations include: push: add an element the stack. pop: remove and return the top element of the stack . peek: view or “peek at” the top of the stack. empty: determine whether or not there are any elements in the

stack. size: get the number of elements stored in the stack.

We bundle these operations into an interface,

StackInterface<E>,

that declares the methods guaranteed to clients of any class that implements StackInterface<E>.

Page 36: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Implementation

1. public interface StackInterface<E>2. {3. public void push(E x);4. // places x on a stack

5. public E pop();6. // removes and returns the top item7. // returns null if the stack is empty

8. public boolean empty();9. // returns true if no elements are on the stack

10. public E peek();11. // returns the top item, does not alter the stack12. // returns null if the stack is empty13. public int size();

14. // returns the number of items on the stack15. }

Page 37: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Implementation

Problem Statement

Design a Stack<E> class that implements StackInterface<E>. Include a main(...) method that demonstrates the operation of a Stack<E> object.

Use an ArrayList to hold the data of the stack

Page 38: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Implementation

1. import java.util.*; // for ArrayList<E>2. class Stack<E> implements StackInterface<E>3. {4. private ArrayList<E> items;5. public Stack() 6. // default constructor; creates an empty stack7. {8. items = new ArrayList<E>(); // initial capacity is 109. }10. public Stack(int initialCapacity)11. //one argument constructor

//creates a stack with initial capacity initialCapacity12. {13. items = new ArrayList<E>(initialCapacity);14. }15. public void push(E x)16. {17. items.add(x); //uses the ArrayList method add(E o)18. }

Page 39: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Implementation

19. public E pop() 20. {21. if (empty()) // determine whether or not there is an item to remove22. return null;23. return items.remove(items.size()-1)24. //uses the ArrayList method remove(int n)25. }26. public boolean empty()27. {28. return items.isEmpty(); //uses the ArrayList method isEmpty()29. }30. public int size()31. {32. return items.size(); //uses the ArayList method size()33. }34. public E peek()35. {

// determine whether or not there is an item on the stack 36. if (empty())

return null;37. return items.get(items.size()-1); //uses the ArrayList method get(int i)38. }

Page 40: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Line 2: class Stack<E> implements StackInterface<E>

Stack<E> is a generic class. The type parameter E is a stand-in or placeholder for a reference type E.

Line 4: private ArrayList<E> items;Stack<E> data are stored in the ArrayList<E> items.

Lines 5 – 9: public Stack()

// default constructor; creates an empty stack { items = new ArrayList<E>(); // initial capacity is 10 }

By default, the initial capacity of items is 10. Thus, the stack can hold 10 items before the underlying ArrayList<E> must be resized.

The initial stack size is 0. Do not confuse the array capacity with the size of the stack.

Page 41: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Implementation

Lines 10 – 14:

public Stack(int initialCapacity) //one argument constructor

//creates a stack with initial capacity initialCapacity { items = new ArrayList<E>(initialCapacity); }

The one argument constructor sets the initial capacity of items to initialCapacity. The initial stack size is 0 as it is in the default constructor.

Page 42: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Implementation

Lines 15 – 18:

public void push(E x) { items.add(x); //uses the ArrayList method add(E o) }

The push(E x) method places an element x on the top of the stack. The add(E x) method of ArrayList<E> inserts item x of type E at the end of items. The top of the stack is the element at position items.size() – 1.

Page 43: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Implementation

Lines 19 – 25

public E pop() { if (empty()) // determine whether or not there is an item to remove return null; return items.remove(items.size()-1) //uses the ArrayList method remove(int n) }

To remove an item from the stack, first check that the stack is not empty. If there is at least one item on the stack, the call items.remove( items.size() –1) removes the last item that was placed into items. That is, the call removes the element that is on top of the stack, and returns that item.

Page 44: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Example

A Stack For Checking Balanced Parentheses, Brackets,

and Braces

Expressions and statements typically include parentheses, braces and brackets; syntactically correct expressions require balanced parentheses, braces, and brackets. For example, the parentheses in the expression ((2+3) * 3) are balanced; but those in ((2+3) * 3 are not. The parentheses and brackets of array[2*(3+4)] are balanced but the brackets

of array[2*(3+4)[ are not.

Page 45: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Example

With the aid of a stack, determining whether or not the parentheses, braces, and brackets of an expression are balanced is an easy task that is specified by the following algorithm.

initialize a stack to emptyfor each character, ch, of an expression if ch is a left parenthesis (, brace {, or bracket [ push ch onto the stack if ch is a right parenthesis, brace, or bracket if a matching left parenthesis, brace, or bracket is on top of the stack pop the stack else report an error and stop

// No characters remain as input. if the stack is empty, the expression is correctly balanced. Otherwise, it is not

Page 46: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Using a stack to check that ([2+3]–(a +b) +1) is balanced

Stack String Action

empty

([2+3]-(a +b) +1) Push (

( [2+3]-(a +b) +1) Push [

( [ (top) 2+3]-(a +b) +1) read 2

( [ +3]-(a +b) +1) read +

( [ 3]-(a +b) +1) read 3

( [ ]-(a +b) +1) read ]– Pop the matching left bracket [

( -(a +b) +1) read the -

( (a +b) +1) Push (

( ( a +b) +1) read a

( ( +b) +1) read +

( ( b) +1) read b

( ( ) +1) read ) –Pop the matching left parenthesis (

( +1) read +

( 1) read 1

( ) read ) -- Pop the matching left parenthesis (

empty end of string The expression is balanced.

Page 47: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Example

Problem Statement:Implement a class with a single utility method,

public static void boolean expressionChecker( String ex),that determines whether or not theparentheses, braces, and brackets of ex arebalanced. Include a main(…) method thattests expressionChecker(…).

Page 48: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Example

1. import java.util.*;2. public class ExpressionChecker3. {4. public static boolean checkExpression(String ex)5. {6. Stack<Character> stack = new Stack<Character>();7. for (int i = 0; i < ex.length(); i++)8. {9. char ch = ex.charAt(i);

10. // if ch is a left parenthesis, brace, or bracket push ch onto the stack11. if (ch == '(' || ch == '[' || ch == '{') 12. stack.push(ch);

13. // if ch is a left parenthesis and there is a matching right parenthesis //on the stack, pop

14. else if (ch == ')' && (!stack.empty()) && stack.peek().equals( '('))15. stack.pop();

16. // if ch is a left bracket and there is a matching right bracket on the stack, pop17. else if (ch == ']' && (!stack.empty()) && stack.peek().equals( '['))18. stack.pop();

Page 49: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Example

19. // if ch is a left brace and there is a matching right brace on the stack, pop20. else if (ch == '}' && (!stack.empty()) &&

stack.peek().equals('{'))21. stack.pop();

22. // if ch is a left parenthesis, bracket, or brace with no match on the stack,error23. else if (ch== ')' || ch == ']' || ch == '}')24. return false; // expression is incorrect25. }26. if (!stack.empty()) 27. return false;28. return true;29. }

Page 50: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Example

30. public static void main(String [] args)31. {32. Scanner input = new Scanner(System.in);33. System.out.println("Enter an expression; press <ENTER> to exit");34. System.out.print(": ");35. String expression = input.nextLine();36. do37. {38. boolean correct = checkExpression(expression);39. if (correct)40. System.out.println("Expression "+ expression+ " is correct");41. else42. System.out.println("Expression "+ expression+ " is incorrect");43. System.out.print("\n: ");44. expression = input.nextLine();45. } while (!expression.equals(""));46. }47. }

Page 51: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Example

Output:Enter an expression; press <ENTER> to exit: (1+3)* (3+5)*4Expression (1+3)* (3+5)*4 is correct

: (1+3)*x[3-2]+(a+5Expression (1+3)*x[3-2]+(a+5 is incorrect

: array[3+(4+5]Expression array[3+(4+5] is incorrect

Page 52: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Stack Example

Discussion

The statement on line 6 instantiates a Stack<Character> object. However, the statement on line 12

stack.push(ch);

pushes a primitive value onto the stack.

Autoboxing invisibly wraps the value of ch with a Characterobject. The statement stack.push(ch) is akin tostack.push(new Character(ch)).

Page 53: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue

A queue is an ordered list of data into which data can be inserted and removed. However, unlike a stack, data is always inserted at one end of a queue, the rear, and removed from the other end, the front.

Page 54: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue vs. Stack

Page 55: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

Typical queue operations include:

insert: add an item to the rear of the queue. remove: remove and return an item from the front of the

queue. peek: view or “peek at” the front item. empty: determine whether or not there are any elements in

the queue. size: get the number of elements stored in the queue

Page 56: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

The queue operations are specified the following generic interface:

public interface QueueInterface<E>{ public void insert(E x); // inserts x at the rear of the queue public E remove(); // removes and returns the front item // returns null if the queue is empty public boolean empty(); // returns true if no elements are in the queue public E peek(); // returns the front item, does not alter the queue // returns null if the queue is empty public int size(); // returns the number of items in the queue

}

Page 57: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

We can implement a queue using an ArrayList<E> for storage. However,this is not the most expedient implementation.

Suppose, for example, that items is an ArrayList<E> and that items holds queue elements. T

he insert() operation can be implemented as: void insert(E x) { items.add(x):

}which places element x at the end of items.

The method is easy and efficient.

Page 58: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

On the other hand, the remove() operation, although easy to implement, is not particularly efficient. If the first queue element is always located at position 0, the remove operation can be implemented as:

E remove() { if (empty()) return null; return items.remove(0); }

The method works correctly but at a cost. When the element at position 0 is deleted from an ArrayList<E> object, all other elements in the list are shifted. That is, the element in position 1 is moved to position 0, the element in position 2 is moved to position 1 etc. So every remove() operation necessitates that all remaining elements in items are moved

Page 59: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

A queue can be more efficiently implemented using a simple array for storage. The only real limitation with such an implementation is that the size of an array is fixed. However, if you can estimate the maximum size of a queue,

an array implementation is a good option.

Page 60: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

A queue that uses an array, items, with maximum capacity 5. The variable front holds the index of the first item in the queue and a secondVariable rear holds the index of the last item in the queue. The queue after fourinsert operations; (b) after two remove operations , and (c) after one moreInsert operation.

Page 61: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

. Will one more insert() operation throw an ArrayOutOfBoundsException? Not necessarily.

There are two available cells in the array: items[0] and items[1]. If the next insert operation, insert("Saturn"), places "Saturn" in items[0], then no error occurs.

That is, we consider items[0] to be the cell that follows

items[4]. In practice, we imagine the array as circular.

Page 62: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

By using “circular array,” we do not waste any array locations, and the queue can hold as many elements as the size of the underlying array. Nevertheless, overflow errors can still occur once we use all the space in the array.

Page 63: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

Problem Statement:Implement a queue using an array for storage. The

Queue<E> class should implement QueueInterface<E>.

Page 64: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

SolutionThe Queue<E> class uses an array, items for storage. There are also four

integer fields: front, which holds the index of the first item in the queue, rear, which holds the index of the last item in the queue, numItems, which stores the number of items in the queue, and maxQueue, which stores the maximum capacity of the queue.

The array, items, is considered circular. This means that, if space remains, items[0] is the storage location following items[maxQueue-1], where maxQueue is items.length.

Because an array has a fixed size, it is possible to exceed the capacity of a queue. In this case, the insert() method issues a message and exits. Alternatively, insert() might throw an exception.

Page 65: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

1. import java.util.*;2. public class Queue<E> implements QueueInterface<E>3. {4. private E[] items;5. private int numItems; // number of elements currently in the queue6. int front, rear; // holds the indices of the front an rear elements7. int maxQueue; // maximum capacity 8. public Queue() // default constructor, sets maxQueue to 109. {10. items =(E[]) new Object[10];

// new E[10] is illegal; the cast is necessary11. numItems= 0;12. front = rear= -1; // -1 indicates that the queue is empty13. maxQueue = 10;14. }15. public Queue(int max)

// one argument constructor , accepts maximum capacity16. {17. maxQueue = max;18. items =(E[]) new Object[maxQueue];

// new E[maxQueue] is illegal; the cast is necessary19. numItems = 0;20. front = rear= -1; // -1 indicates that the queue is empty21. }

Page 66: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

22. public void insert(E x)23. // inserts x at the rear of the queue24. // if overflow occurs, issues a message and exits25. {26. if ( numItems == maxQueue) // queue is full27. {28. System.out.println(" Queue Overflow");29. System.exit(0);30. }31. rear = (rear +1) % maxQueue; // % maxQueue ensures wraparound32. items[rear] = x;33. numItems++;34. if (numItems == 1) // if queue was previously empty35. front = rear;36. }

Page 67: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

37. public E remove()38. // removes and returns the first item in the queue39. // if the queue is empty , returns null40. {41. if (numItems == 0) // empty queue42. return null;43. E temp = items[front]; // holds the first item in the queue44. numItems--;45. if ( numItems == 0) // if the queue is now empty set front and rear to –146. front = rear = -1;47. else48. front = (front + 1) % maxQueue; // %maxQueue ensures wraparound49. return temp;50. }51. public E peek()52. // returns the first item in the queue or null if the queue is empty53. // does not alter the queue54. {55. if (numItems == 0) // empty queue56. return null;57. else58. return items[front];59. }

Page 68: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

60. public boolean empty()61. // returns true if the queue is empty62. {63. return numItems == 0;64. }65. public int size()66. // returns the number of items currently in the queue67. {68. return numItems;69. }

Page 69: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

Discussion

Lines 10 and 18:

items =(E[]) new Object[10]; items =(E[]) new Object[maxQueue];

Java does not allow generic arrays. The statement

items = new E[10];

results in a compilation error.

To avoid this error, we instantiate an array of Object and cast that to E[]. When the class is compiled the compiler issues a warning to the effect

that the cast on lines 10 and 18 may be unsafe. However, no problem occurs here because every item in the queue belongs to the class represented by E.

Page 70: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Queue Implementation

Lines 31 and 48:

rear = (rear +1) % maxQueue; front = (front+1) % maxQueue;

These lines effect wraparound. For example, suppose that that maximum capacity of a queue is 10, and that the queue consists of three items stored at items[7], items[8], and item[9]. Since the value of rear is 9,

rear = (rear+1)% maxQueue = (9+1)% 10 = 0.

Thus, the next item is stored at items[0]. The array is circular; 0 follows 9.

Page 71: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Linked List

A linked list is an ordered collection, group, or list of items such that each item holds a reference or “link” to the next item of the collection.

Page 72: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Linked List

To implement a linked list we use nodes

A node is an object that contains data as well as a reference to another node. Thus, a node has at least two fields, one of

which holds the address of another node

Page 73: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

A Node class

public class Node{

public String data; public Node next; // next is a reference to a Node

public Node () // default constructor{ data = “”; // the empty string next = null;}

public Node(String s) // one argument constructor{ data = s;

next = null;}

}

Page 74: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Node

The data type of next is Node. The next field of a Node is itself a reference to a Node

object. The next field holds the address of another node. Node is a recursive structure.

Page 75: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Node

The statements

Node p = new Node("Mercury"); // one-argument constructor Node q = new Node ("Venus");

instantiate two Node objects, one referenced by p and anotherreferenced by q.

Page 76: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Node

Nodes can be linked together to form a “chain of nodes.”

The horizontal arrow indicates that the field p.next (in the “Mercury” node)holds the address of the “Venus” node, which also happens to be stored inq.

The linking of these two nodes is accomplished by the statement

p.next = q; //q holds the address of the “Venus” node,

which assigns the address of the “Venus” node (q) to the next field of the“Mercury” node (p.next).

Page 77: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Node

Four linked nodes

Page 78: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Creating a Chain of Nodes

Page 79: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Creating a Chain of Nodes

Page 80: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Chain of Nodes

Problem StatementImplement a class, Chain, that creates a chain of Node objects

such that each Node holds a String entered via the console. Include a method that displays the data stored in the chain.

Page 81: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Chain of Nodes

In the following application note that a private Node class is declared within Chain; and

a reference front holds the address of the first node in the

chain. Without such a reference, the data in the chain is inaccessible. The reference front serves as an anchor for the chain of nodes.

Page 82: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Chain of Nodes

1. import java.util.*;2. public class Chain3. {4. private class Node // a class declared within Chain, an inner class5. {6. private String data;7. private Node next;

8. public Node() // default constructor9. {10. data = “”;11. next = null;12. }13. public Node(String s) // one argument constructor14. {15. data = s;16. next = null;17. }18. }

Page 83: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Chain of Nodes

19. public Chain() // constructor builds a chain20. {21. Scanner input = new Scanner(System.in);22. String name;23. Node q, r; 24. System.out.print("Enter name -- Press <Enter> to signal end of data: " );25. name = input. nextLine();

26. // create the first node27. front = new Node(name);28. q = front; // front and q both reference the first node29. System.out.print("Enter name: " );30. name = input. nextLine();

31. while (!name.equals(""))32. {33. r = new Node(name); // get a new node 34. q.next = r; // link the previous node to the new node35. q = r; // move q to the "new" node36. System.out.print("Enter name: " );37. name = input. nextLine(); 38. }

Page 84: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Chain of Nodes

39. public void printChain()40. {41. Node q = front; // q references the first node in the chain42. System.out.println("\nThe names in the chain of nodes are: ");43. while (q!= null)44. {45. System.out.println(q.data);46. q = q.next; // move q to the next node in the chain47. }48. }49. public static void main(String[] args)50. {51. Chain chain = new Chain();52. chain.printChain();53. }54. }

Page 85: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Node, an inner class

Node is declared as a private class declared within another class, Chain. Node is declared solely for Chain’s convenience. Node is called an inner class and Chain, an outer or surrounding class.

Inner classes are useful when one class has meaning only in the context of another class. For example, on its own, a Node may have no apparent purpose, but a part of a chain, a Node object has a well-defined function.

The methods of an inner class have direct access to variables and methods of the surrounding outer class. On the other hand, the methods of an outer class can access an inner class field or invoke an inner class method only via an object of the inner class. For example, consider the following class definitions.

Page 86: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Linked List

Because each node in a chain holds the address of the next node, a chain of nodes suggests a natural storage structure for a linked list class, LList<E>.

In addition to the instance variable front, which references the first node of the chain, LLInk<E> includes a field, rear, which holds the address of last node, and a third reference variable current, which can reference any node in the chain.

Page 87: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Linked List

The methods of LList<E> include methods for adding, removing, and retrieving data. That is, the methods of LList<E> mirror the methods of ArrayList<E>. These methods, common to ArrayList<E> and LList<E>, are grouped together in the following interface

Page 88: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ListInterface

public interface ListInterface<E>{void add(int index, E x); // inserts x into position index

void add(E x); // adds x to the end of the list

void clear();// removes all objects from the list

boolean contains ( E x); // returns true if x is a member of the list

E get(int index);// returns the Object at position index

Page 89: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

ListInterface

boolean isEmpty(); // returns true if the list has no elements

boolean remove (E x);

// if x is a member of the list, removes the first occurrence of x from the// list, shifts all elements // and returns true; otherwise returns false.

E remove (int index); // removes and returns the object x at position index; // shifts all elements following x down one position

E set (int index, E x); // replaces the object at index index with x; returns the replaced object.

int size(); // returns the number of objects currently in the list }

Page 90: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Linked List

The LList<E> class not only implements ListInterface<E> but also provides three additional methods, not found in ArrayList<E>,

void reset(),sets current equal to front

boolean hasNext() returns true if current.next is not null, i.e. if current is not equal to rear.

E next(). if current == null, reports an error and terminates the application; otherwise

returns the data of the current node and moves current down the list, i.e. sets current equal to current.next.

Page 91: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

LList<E>

1. public class LList <E> implements ListInterface<E>2. {

3. private class Node // an inner class4. {5. private E data;6. private Node next;

7. public Node() // default constructor8. {9. data = null;10. next = null;11. }12. public Node(E x) // two argument constructor13. {14. data = x;15. next = null;16. }17. } // end

Page 92: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

LList<E>

18. private Node front, rear, current;19. private int length; // the size of the list20. public LList() // default constructor21. {22. rear = front = current= null;23. length = 0;24. }

25. public void add(E x) // adds x to the end of the list26. {27. Node p = new Node(x); // instantiate a new node referenced by p28. if (rear == null) // if list is initially empty29. front =rear = p; // the list has just one node 30. else31. {32. rear.next = p; // places the Node referenced by p at the end 33. rear = p; 34. }35. length++;36. }

Page 93: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

37. public void add(int index, E x) // adds x to list at position index38. {39. if (index > length ) // index out of range40. {41. System.out.println("Out of range in add(int index, E x)");42. System.exit(0);43. }44. Node p = new Node(x); // instantiate a new node referenced by p45. // add to the front of the list46. if (index == 0) 47. {48. p.next = front; // place the address of the first nod into the new node49. front = p; // front references the new node 50. if (rear == null) // if list was initially empty51. rear = front; // front and rear reference the single node of the list52. length++;53. return;54. }

Page 94: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

55. // add to the end of the list56. if (index == length)57. {58. add(x); 59. return;60. }

61. // addition is neither at front nor rear62. Node q = front; 63. for (int i = 0; i < index-1; i++) // point q to the node at position index64. q = q.next;65. Node r = q.next; // r references the node following q (could be null)

66. q.next = p; 67. p.next = r; 68. length++;69. }70. public void clear() // makes the list empty71. {72. front = rear = null; 73. length = 0;74. }

Page 95: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

75. public boolean contains (E x) // returns true if x is a member of the list76. {77. Node p = front; 78. for (int i = 0; i < length; i++) // could also use “(while p.next != null)”79. {80. if ( x.equals(p.data)) 81. return true;82. p = p.next; 83. }84. return false; // search unsuccessful85. }86. public E get (int index) // returns data at position index87. {88. if (index >= length) // if index is out of bounds89. {90. System.out.println("Error in get (int index)");91. System.exit(0);92. }93. Node p = front;94. for (int i = 0 ; i < index; i++) 95. p = p.next; // move through the list, node by node96. return p.data;97. }

Page 96: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

LList<E>

98. public boolean isEmpty() // returns true if list is empty99. {100. return length == 0;101. }102. public boolean remove (E x) // removes first occurrence of x; 103. // returns true if successful

104. {105. Node p = front; 106. Node q = null; 107. while (!(p == null) && !x.equals(p.data)) // look for x108. {109. q = p; 110. p = p.next; 111. }112. if (p == null) // not found113. return false;114. if (!(q == null)) // if x is in the first node q is null115. q.next = p.next;116. if (p == front)117. front= front.next;118. if ( p == rear)119. rear = q;120. length--;121. return true;122. }

Page 97: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

LList<E>

123. public E remove (int index) // removes and returns data at position index124. {125. if (index >= length) // index out of bounds126. {127. System.out.println("Error in remove (int index)");128. System.exit(0);129. }130. Node p = front;131. Node q = null; 132. for ( int i = 0; i < index; i++) // q follows p down the list133. {134. q = p;135. p = p.next;136. }137. if ( current ==p) // if removing the current node, move current to the next node138. current = p.next;139. if (!(q == null)) // if not removing the first node140. // q follows p, so q is null when p is the first node.141. q.next = p.next;142. if (p == front) 143. front= front.next;144. if ( p == rear)145. rear = q;146. length--;147. return p.data;148. }

Page 98: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

LList<E>

149. public E set (int index, E x) // sets data at position index to x150. {151. if (index >= length) // index out of bounds152. {153. System.out.println("Error in get (int index)");154. System.exit(0);155. }156. Node p = front;157. for ( int i = 0; i < index; i++)158. p = p.next;159. E temp = p.data;160. p.data = x;161. return temp;162. }163. public int size() // returns the number of data on the list164. {165. return length;166. }

Page 99: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

LList<E>

167. public void reset() // makes the first node the current node168. {169. current = front;170. }171. public boolean hasNext() // returns true if a call to next() will be successful172. {173. if (current == null)174. return false;175. return true;176. }177. public E next() // returns data of current node and moves current to the next

node178. {179. if (current == null)180. {181. System.out.println("Error in hasNext() ");182. System.exit(0);183. }184. E temp = current.data;185. current = current.next;186. return temp;187. }188. }

Page 100: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Lines 25- 36: void add(E x)

This method adds a node with data x to the rear of the list.Suppose that a list consists of three nodes:

The method call add(8) results in the following actions.

Page 101: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Lines 25- 36: void add(E x)

Line 27: Node p = new Node(8);

Line 33: rear.next = p;

Line 33: rear = p;

Page 102: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Lines 123- 148: E remove(int index)

This method removes the node at a given index. For example, remove(0) removes the first node in the list and remove(2) removes the third node in the list.

Trace a call to remove(2).

Page 103: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Lines 123- 148: E remove(int index)

Lines 132-136: for ( int i = 0; i < index; i++) { q = p; p = p.next; } For i = 0 and i = 1, set q equal to p, and move p down the list.

Notice that q follows p.

Page 104: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Lines 123- 148: E remove(int index)

Lines 137-138: if ( current ==p) current = p.next;

p references the node which is to be removed. If current references the same node as p, move current down the list

Page 105: Java Programming: From the Ground Up Chapter 16 Data Structures and Generics

Lines 123- 148: E remove(int index)

Lines 139-141: if (!(q == null)) q.next = p.next;

If q is null, then the node to be removed is the first node on the list.

In thiscase, q is not null. Here, p holds the address of the node that is to beremoved and q the address of the preceding node. Change the link inq.next from p to p.next.