Test 2 Flashcards

1
Q

generic type

A

a class or interface type that has another type as a parameter. Here are some examples:

A list in which all elements are the same type. The element type is the parameter.
An ordered pair in which both elements are the same type. The element type is the parameter.
A key-value pair in which all the keys are the same type and all the values are the same type. There are two parameters, one for the key type and another for the value type.
A comparable type in which two objects of the same type can be compared to determine which is larger.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

formal type parameter

A

For each declaration, the item in braces is the formal type parameter.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

actual type argument

A

An instantiation of a generic type, in which the actual type argument is supplied for the formal type parameter, is called a parameterized type. Here are some instantiations of the types listed above.

MyList
MyList

Important: The actual type must be a class or interface type. You cannot instantiate with primitive types.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

code shows how OrderedPair can be instantiated and used.

A
OrderedPair<>Stringparents = new OrderedPair<>String("mom", "dad");
// Could initialize as parents = new OrderedPair<>("mom", "dad");
String helen = parents.getX();
Notice that the constructor name does show the actual parameter type even though the constructor definition does not. An alternative allows you to use the parameter with just the diamond notation, <>, without specifying the actual parameter type.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Parameterized types as method arguments and return types

A

public double slope(OrderedPair<>Double p1, OrderedPair<>Double p2) {
double numerator = p1.getY() - p2.getY();
double denominator = p1.getX() - p2.getX();
return numerator/denominator;
}

You must specify the type parameter (that is, use a parameterized type) for these kinds of arguments and return types.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

interface types is Comparable

A

public int compareTo(T x)

The compareTo() method should impose a full ordering on all instances of T (allowing any list of instances of T to be sorted). It returns a negative number if this object is less than x, positive if this is greater than x, and 0 if this object and x are the same.
ex. public class StoreProduct implements Comparable<>E{
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Wildcards

A

If you want a generic type argument that is independent of a particular parameterized, you can use a type wildcard, which is indicated by <>?. The following method, which belongs to a class named Driver, prints the data members of its actual argument in reverse order.

public void printReverse(OrderedPair<> ?p) {
Object x = p.getX();
Object y = p.getY();

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Generic restrictions

A
You cannot create a parameterized type from a primitive. You must use a class or interface type.
You cannot declare a static member variable of a generic type with the type parameter.
You cannot create arrays of parameterized types.

The following section and the code below show how to deal with the first restriction on primitives.

You cannot declare a static member of a generic type because the static member is a class variable. The type would be different for each parameterized type instantiation of the generic type.

You cannot create arrays of parameterized types, but you can work around that restriction. This code illustrates how.

// OrderedPair badPoint; // ILLEGAL

OrderedPair goodPoint; // This is the primitive workaround

// OrderedPair [] badArray                  // ILLEGAL
//          = new OrderedPair[30] badArray; // ILLEGAL
Object[] goodArray = new Object[30];  // This is the array workaround
goodArray[0] = new OrderedPair("hello", "goodbye");
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Wrapper classes

A

Each primitive type has an associated wrapper class, whose name reflects the type. For example, Boolean wraps a boolean value, Integer wraps an int, and Double wraps a double.

You can construct a wrapper class type object by using a primitive or by using a string representation of the primitive. The following are examples.

Double dbl = new Double(1.23);

Each wrapper class has methods that returns the value of the primitive equivalent. The following code assigns 567 to both x and y. Note that getInteger() is a static method in the Integer class.

Integer xObject = new Integer("567");
int x = xObject.intValue()
int y = Integer.getInteger("567");
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

boxing

A
The Java compiler automatically converts primitives to their corresponding wrapper class types as needed. This conversion is called boxing (automatic = auto boxing).
ex.
// Calling code
ArrayList<>Integer measures = new ArrayList<>();
measures.add(12);
measures.add(7);
measures.add(30);
int sum = measures.get(0) + measures.get(1); // sum is 19
if (measures.contains(7)) {
   // You can also add without boxing
   measures.add(2, new Integer(22));
   printList(measures);
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

collection

A

A collection is an object that holds multiple objects at the same time. The objects in a collection are called elements. The Java API contains several top-level collection interfaces:

Collection
Set: cannot contain duplicate elements.
List: a sequence of elements.
Queue: holds elements awaiting processing.
Map: elements have key-value pairs. The key provides a look-up for its corresponding value. Duplicate keys are not allowed.

When you create a collection object, you should indicate the type of element the collection has.

Elements belonging to collections are objects. They cannot be primitives. In order to have an ArrayList of ints, you need to use the Integer wrapper type instead. The following statement is an example.

ArrayList score = new ArrayList()
Can also declare as List (more flexible)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Java collections framework

A

-Set
HashSet. The most commonly used because it is the most efficient. Hashing computes a unique value for each element of the set, so any particular element is quick to look up even if the set is very large.
TreeSet. Imposes an order on the elements.
LinkedHashSet. A cross between HashSet and TreeSet.
-List
ArrayList. The most commonly used, this list type has indexes to access elements.
LinkedList. List elements are not indexed, so access to elements is not efficient.
-Map
HashMap. The most commonly used, each element (which is a key-value pair) has a hash to determine its location. Hashing makes this an efficient data structure.
TreeMap. Helpful if the keys should be stored in a particular order.
LinkedHashMap. Can change the order of storage of elements depending on when they were last accessed.
-Queue
LinkedList. The most commonly used, elements are removed from the front of the queue (the LinkedList) and added to the rear.
PriorityQueue. Elements are ordered so that the smallest element is always at the front. Removing the smallest element re-orders the rest of the queue to bring the smallest remaining element to the front.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Iterating through collections with for-each loops

A

Iterating through a collection (or any aggregate data type) means going through the collection, processing one element at a time. When you simply want to examine each element without changing it, the easiest way to iterate through an entire collection is to use a for-each loop.

for (element-type element-name : collection-name) {
do something with element-name
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

iterator

A

Whenever possible, you should use for-each loops to iterate through collections. That does not work if you want to change the collection while you are going along. In that case, you can use an iterator, which is an object capable of iterating through a collection. An iterator starts at the first element, then can go to each next element in succession.

Iterator is an interface in java.util. It declares three important methods:
boolean hasNext()
 next()
void remove()- 	Removes from the collection the last element returned by the iterator.

The Collection interface declares an iterator method, which is defined in all of the concrete implementing classes:

Iterator iterator()

The return type for this method is an interface type. The actual runtime type of the object returned does not matter. What is critical is that object supports all of the Iterator methods. The object starts its iteration at the beginning of the collection, going to each successive element with each next() message

Collection<>String words = new HashSet<>();
// Add some Strings to word.
...
int twoCharacterWords = 0;
Iterator<>String iter = words.iterator();
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

list

A

A list is a collection whose elements come in a distinct order. In other words, there is a first element, a second element, and so on. (It is easy to define a list recursively. A list is either empty or it consists of an element plus another list.)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Two kinds of lists

A

Array list: a list in which the elements are stored in contiguous memory (an array).
Linked list: a list in which the information in each element includes the location of the subsequent element.
Choosing list types: The type of list that you choose depends on what kind of operations you want to perform on it. If you want to be able to insert or delete items efficiently, a linked list is likely the way to go. If you want efficient access to elements via their indexes, an array list is probably the better choice.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

array list

A

An array list is a list in which the underlying data structure that holds the elements is an array. The Java class for implementing an array list is the generic type ArrayList<>E, where the parameter E is the type of list elements. The list size is the number of list elements. The length of the underlying array is the capacity of the array list, and it is always at least as large as the list size. The capacity automatically increases if needed as the list size grows.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Vectors:

A

Java also has a Vector class for implementing array lists. The Vector class and the ArrayList class provide the same kinds of operations, but Vectors are much less efficient than ArrayLists.

You should use Vectors only when your program has multiple threads that need to access the list elements. (Vectors are “thread safe.”)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

LinkedLists

A

Linked lists are lists in which the information in each element includes the location of the next element. The LinkedList class is particularly convenient for creating special list types such as stacks and queues.

LinkedList implements List, so it defines all of the List methods. It also defines methods to get, remove and insert an element at the beginning and end of the list:

Array lists, which are based on arrays, must shift elements in order to do insertions or deletions. Such shifts are not necessary for linked lists. In order to insert or delete an element in a certain position, it is simply necessary to change the location information in the elements immediately before and after the one to be inserted or deleted.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Doubly linked lists:

A

Java’s LinkedList class is “doubly-linked.” That means information in each element includes the location of the element that follows it as well as the location of the element that precedes it.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Sets

A

Lists hold their elements in sequences – list elements have indexes. Sets are groups of elements in which there is no sequencing. Furthermore, sets cannot contain duplicate elements.

Set is an interface in Java that extends Collection. The table below lists some of the Set methods.

Method	Description
void add(E x)	Adds x to the set if it is not already in the set.
void remove(E x)	Removes x from the set if it is an element of the set.
boolean contains(E x)	true if x is an element of the set.
boolean isEmpty()	true if the set contains no elements.
int size()	Number of elements in the set.

For sets, you need to use for-each loops for simple traversals. But those loops are inappropriate if you want to change the elements in the collection. For that task, you need a special object called an iterator. Iterators can go through all the elements of a collection, enabling you to access them one-by-one.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

There are two classes that implement Set

A

HashSet and TreeSet. Since they offer the same basic methods, which of those two you choose to use depends on the performance required. HashSets are more efficient. If you want to sort the elements, however, use a TreeSet.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

ConcurrentModificationException

A

That is not so nice. If you try to remove and element from the underlying set (or any collection) inside the for-each loop, you get a ConcurrentModificationException. Using an iterator avoids that issue.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

buffer

A

With respect to computer programming, the term buffer means a place in main memory to store varying amounts of data. There are StringBuffers, for example, for storing and manipulating string data. Consider this problem:

Maintain statistics on test scores for students in a class.

If the maximum possible class size is 200, then this array can be a buffer to store the scores.

int[] test = new int[200];
And to keep track of the number of test scores, you can do this:

int size = 0;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

sentinel value

A

(Alternatively, you could have a sentinel value such as -1 to mark the end of the list of test scores. The sentinel value would have to be a number that could not possibly be a legitimate score.)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

What is a custom list?

A

A list is an ordered collection of elements. Common list operations include:

add – adds a new element to the list
remove – removes an element from the list (and returns it)
get – returns a list element (from a particular position or satisfying a particular condition)
contains – determines if a particular item belongs to the list
size – number of elements in the list

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

ArrayList and LinkedList will do. But sometimes you need a custom list to do things such as:

A

Restrict list elements (such as no null elements or no negative numeric elements) and throw custom exceptions on attempts to add illegal elements.
Support special operations not common to all lists.
Progam efficiently for particular operations (such as add to front).
Create self organizing lists (such as move-to-front lists and move-ahead-one lists, where the order of list items changes dynamically according to the most recent search).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q

The custom array list requires three attributes:

A

An array to hold the elements. The type must be E[], where E is the type parameter for the generic list class.
An int for the list size (the actual number of list elements).
An int for the capacity (number of array elements).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q

Creating generic arrays- Constructor for custom ArrayList

A

private E[] list;
public SimpleArrayList(int capacity) {
if (capacity < 0)
throw new IllegalArgumentException();
this.capacity = capacity;
Object[] temp = new Object[capacity];
list = (E[]) temp;
}

30
Q

Restricting generic element types

A

public class ListOfNumbers<>E extends Number{
private E[] list;
public ListOfNumbers() {
Number[] temp = new Number[capacity];
list = (E[]) temp;
}

31
Q

Testing list code

A

List operations should be coded correctly for each of the following 4 situations:

The operation changes/accesses the list at the front.
The operation changes/accesses the list at the end.
The operation changes/accesses the list in the middle.
The list is empty.
After each operation, make sure that:

The list has the correct number of elements.
The elements are correct and in the correct order.
Test combinations of operations such as multiple adds/removes, an add followed by a remove, and so on..

32
Q

nested class

A

A nested class is a class whose definition is inside another class. A non-static nested class is also called an inner class.

33
Q

Reasons for nested classes

A

Good logical grouping of classes that are used in one place.
Better encapsulation.
Easier to read and maintain code.

34
Q

Declaring nested classes

A
Public vs private. If a nested class is to be used only by the outer class, make it private. It is legal to declare nested classes as public, protected, or package private (with no access specifier).
Member access. If a nested class is public, its members should be private. If the nested class is private, then you can make its members public. This makes for simpler syntax.
Static. Unless the nested class needs to access members of the outer class, you can make it static. A nested class can have static and non-static members.
Public vs private nested classes: If you make a nested class public, you can access it outside of the enclosing class. In that case, the fully qualified name of the nested class has the form:
.
35
Q

How do you decide whether to declare nested classes as static or as inner (non-static)? Here are some issues to consider:

A

Nested classes that are declared as static cannot use any of the instance variables of the outer class. Inner classes, however, can use any instance variables of the outer class, even private ones.

Static nested classes cannot access instance variables or instance methods of the outer class.
Inner classes can access every member of the outer class.
Inner classes cannot have static members.
If the nested class could potentially be standalone, make it static. It would have no need to access the private data or methods of the outer class at all.
36
Q

dereferencing

A

means using the name (reference) of an object to access the object (s.length() for ex)

37
Q

NullPointerException

A

occurs when you try to dereference null

38
Q

linked list

A

element in the list. The list data can be any type. The location, which is a reference to the next list element, is called a link. The elements of linked lists (data and links) are called nodes.

39
Q

head

A

The first element is the list head. From the head, you can get to the second element. From the second, you can get to the third, and so on. The link for the last node in the list is null.

40
Q

Setting up a linked list class

A
public class LinkedList {
   Node head;  // Reference to the first element in the list

// List elements are Nodes
private class Node {
public Object data;
public Node link;

      // You must create a new Node with data and a reference to the next element.
      public Node(Object data, Node link) {
         this.data = data;
         this.link = link;
      }
   }
   /**
    * Constructor -- creates an empty LinkedList.
    */
   public LinkedList() {
      head = null;
   }
}
41
Q

Adding an item to the front of a linked list

A

Create a new node with the item you want to add and with a reference to the current front element. The new node in the figure below contains the data element E.
Change head to reference the new node.

Inserting a new item at the front of a linked list is much simpler than inserting a new item at the front of an array-based list. The linked list code, which requires no shifting, is much easier to write and much more efficient.

42
Q

Removing the item from the front of a linked list

A

Removing the item from the front of a linked list is a 1-step process. Simply make the head point to the second node (or null, if there is no second node).

The old first node is no longer in the list. You cannot get to it from any other list node and you cannot get to it from head.

It is critical in this code that we check to make sure the list is not empty before trying to access the first item. If we failed to do that, we run the risk of a NullPointerException.

43
Q

Traversing a linked list

A

Traversing a list means looking at the list items, one-at-a-time, starting from the front. “Looking at” can mean any operation that does not change the items themselves, such as printing them, counting them, and so on.

To traverse an array-based list, use an integer counter to go through the list indexes, beginning at 0 and stopping just before the list size. To traverse a linked list, use a pointer (a reference to a node) to go through the list nodes, beginning at the head and stopping at null. Start with this assignment:

p = head;

44
Q

Traversal paradigms: You can use a while loop or a for loop to traverse a list.

A

The paradigm for a while loop traversal is:
Node p = head;
while (p != null) {
//….
p = p.link;
}
The paradigm for a for loop traversal is:

      for (Node p = head; p != null; p = p.link) {
         //....
      }
45
Q

Checks for linked list algorithms: At a minimum, you should go through this series of checks for your linked list code:

A

Is the code correct if the list is empty?
Is the code correct if the data item is to be added/removed/changed at the beginning of the list?
Is the code correct if the data item is to be added/removed/changed at the end of the list?
Is the code correct if the data item is to be added/removed/changed at the middle of the list?

46
Q

Checking for empty and searching for linkedlist items

A
public class LinkedList {
   Node head;  // Reference to the first element in the list  
   // ...
   /**
    * Does this list have any data?
    * @return true if the list has no data, return false if the list has data.
    */
   public boolean isEmpty(){
      return head == null;
   }
47
Q

To determine if a list contains a particular item, we need to traverse the list looking for it.

A

The data in our LinkedList elements are Objects. This means we can store any class type data in the list. We do pay a price for that general representation if we want to perform operations on the data itself. We first need to find out what type it is before we can perform anything but generic operations.

When we are searching for a particular data item in the list, we need to compare the data for each list element to the item to see if they match. We use the equals() method of the Object class in our search.

48
Q

Removing an item from a linked list

A

The code to remove the item is a little complicated. By the time you find the item to remove, you have passed the element whose link you need to change. One way to deal with this is to take a pair of pointers down the list, one following the other. When the first pointer finds the item to be removed, the pointer that follows can be used to change the link of the previous element.

   public void remove(Object x){
      Node current = head;  // First pointer to travel down the list
      Node previous = null; // Follows the first pointer
      // Search for x
      while (current != null &amp;&amp; !current.data.equals(x)) {
         previous = current;
         current = current.link;
      }
      // If you don't drop off the end of the list, there is work to do!
      if (current != null) {
         if (current == head){ // Is x the first list item?
            head = head.link;
         }
         else { // x is somewhere after the first item
            previous.link = current.link;
         }
      }
49
Q

Generic vs data being specific object type

A
LinkedList class declaration stays the same, not <> object type, data member type however changes to whatever type object the list is comprised of 
ex. String data;
50
Q

algorithm

A

An algorithm is a step-by-step description of how to solve a problem.

Example problem: (Search) Determine if a particular item belongs to a list.

Algorithm: Go through the list elements, one-at-a-time starting from the front. For each element, compare it to the item you are searching. Stop when there’s a match (true) or when you run off the end of a the list (false – no match).

51
Q

Algorithm efficiency

A

The efficiency of an algorithm is a measure of how quickly it executes or how much memory it requires as a function of the size of the input. (Size of theinput? Think number of elements in the list, for example.) Since algorithms can be implemented in many languages and executed on many machines, actual time of execution of an algorithm has little meaning. A theoretic approach to algorithm efficiency independent of language or machine is to count the number of times each single statement executes during execution. In most cases, that count depends on the amount of data the algorithm must process.

The count of statement executions corresponds directly to execution time. In formal terms, the time required for an algorithm to solve a problem is a function T(n), where n is the size of the instance of the problem (for example, n is the number of elements in the list or the number of elements to sort.)

52
Q

worst-case time complexity

A

The worst-case time complexity is the maximum time taken (number of statement executions) over all inputs of size n.`

53
Q

polynomial time algorithm

A

If T(n) is a polynomial, then the algorithm is a polynomial time algorithm. Problems that cannot be solved in polynomial time or less are considered to be intractable

54
Q

computational complexity

A

All of these ideas are part of computational complexity, which is a branch of theoretical computer science and mathematics concerned with the difficulty of problems in terms of how many resources are required (time or space) to solve them.

55
Q

Algorithm efficiency (time efficiency) is measured

A

Algorithm efficiency (time efficiency) is measured by how many simple statements (and simple expressions) are executed for an input of size n. In the worst case, see how many statements are executed for the search code in the first section. Notice that the worst case occurs if the searched for item does not match any list element. (not return statements)

56
Q

big O notation

A

You can estimate the efficiency of an algorithm by big O notation, which characterizes functions by their worst-case time complexities. Big O notation takes into account only the “dominant” part of T(n). For example, if T(n) is n3 + 12n2 + 2100, then the algorithm is O(n3). That’s because the n3 term dwarfs the rest of the terms as n grows large. For simplicity, big O notation ignores constant multipliers as well. The search algorithm of the last section has computational complexity O(n).

57
Q

big O notations for some standard algorithms.

A

Notation Comment Algorithm Example
O(1) time independent of input size (constant)
Looking up the kth element in an array

O(log n) time grows by 1 when the input size is doubled (logarithmic)
Binary search

O(n) time proportional to size of input (linear)
Linear search

O(n log n) best theoretical times for sorts
Mergesort, average time quicksort

O(n2) time proportional to the square of size of input (quadratic)
Elementary sorts - bubble/insertion/selection

O(n!) intractable
Brute force Traveling Salesman Problem solution

58
Q

constant time algorithms

A

Note: Algorithms that are O(1) are constant time algorithms. Their execution time is independent of how much data is under consideration. That’s the best you can do!

59
Q

stack

A

A stack is a special list with a restricted set of operations. The standard stack operations include:

Push: A stack can add new items only at the front, which is called the top of the stack. To push an item on the stack means to add it to the top of the stack.
Pop: A stack can remove only its top item. To pop the stack means to remove that top item, and return it as the value of the operation.
IsEmpty: A stack can tell whether it is empty.
Top (optional): A stack can tell what its top item is (without popping the stack)

Since the last item added to a stack is the first to be removed, a stack is called a last-in-first-out list, or LIFO list.

60
Q

Implementing a stack as a linked list

A

You can implement a stack with a variety of data structures, but the most common implementations are with an array or a linked list.

Head becomes top to follow stack language

isEmpty => return top == null

61
Q

Code reuse: Implementing a stack using composition

A

StackAlternate, the class defined below, is an example of a class that delegates all of its work to an existing class, LinkedList. (Our earlier version of LinkedList, used Objects as the list items. It’s easy to turn that into a generic class.) StackAlternate also gives access only to the stack-type operations of LinkedList. It does not provide access to the non-stack operations.

62
Q

Composition

A

Composition means defining a class that has a member of a different class type. This is not a new idea – for example, we use composition when we create classes with String members.

Composition is useful in delegating the work for a new class to an existing class. It is also useful for cloaking the operations of an existing class when it is to be used in a particular restrictive fashion.

63
Q

Why is composition so useful?

A
Composition is a powerful form of code reuse.
Composition can delegate the work for a new class to an existing class.
Composition can cloak the operations of an existing class when it is to be used in a particular restrictive fashion.
64
Q

Stack application: reversing a list

A

Create a new stack.
Create a pointer initialized to the first element in the list. Go through the list with the pointer – as the pointer accesses each list element:
Push the item for the list element on the stack.
Assign the pointer to the next element in the list.
The pointer travels down the original list, stopping after it drops off the end.
Pop the stack, create a new node with the popped item, and set the head to the new node. The item in the node is the last item of the original list.
Set the pointer that you created in step 2 to the head.
While the stack is not empty:
Pop the stack, create a new node with the popped item, and set the pointer’s link to that new node.
Move the pointer to the new node.

   /**
    * Reverse the order of items in the list.
    */
   public void reverseList() {
      if (head != null) {
         Stack s = new Stack();
         Node p = head;
         // Put all the list items on a stack.
         while (p != null) {
            s.push(p.data);
            p = p.link;
         }
         head = new Node(s.pop(), null);
         p = head;
         // Pop all the items off the stack and add to the end of the list.
         while (!s.isEmpty()) {
            p.link = new Node(s.pop(), null);
            p = p.link;
         }        
      }  
   }
65
Q

queue

A

A queue is a list with a restricted set of operations. Unlike a stack, adds and removes items from the same end, a queue adds items at one end and removes them from the other.

The standard queue operations include:

Add (or enqueue): A queue can add new items only at the back, which is called the rear of the queue.
Remove (or dequeue): A queue can remove only its first item, which is at the front of the queue. Removing an item from the queue returns the front item.
IsEmpty: A queue can tell whether it is empty.
Front (optional): A queue can tell what its front item is without removing.

66
Q

FIFO

A

Since the first item added to a queue is the first to be removed, a queue is called a first-in-first-out list, or FIFO list. Anyone who has ever stood in line waiting for something – to buy tickets or groceries, for example – knows about queues. The standard waiting line is itself a queue (unless, of course, you allow someone to break in line).

67
Q

Implementing a queue as a linked list

A

Implementing stacks and queues: An important characteristic of stacks and queues is that the operations that you can perform on them should take time that is independent of how many items they contain. That is, each operation should have complexity O(1).

What’s needed is a way to make adding a new item to a queue a one-step process. An easy solution is to use two pointers to access the items. One points to the front of the queue (the list of items) and the other points to the rear of the queue.

   /**
    * Constructor -- creates an empty queue.
    */
   public Queue() {
      front = null;
      rear = null;
   }
68
Q

Coding add and remove methods for queue as a linkedlist

A

Since the Queue class has two named pointers, we need to be careful that our add and remove code works for all of these situations:

An empty queue (front == null).
A queue with exactly 1 item (front == rear && front != null).
A queue with more than 1 item.

The add() method shown below deals with an empty queue as a special case. In that situation, both front and rear are set to point to the new element.

The remove() method, shown below, first checks for an empty queue. If the queue is empty, it bails out, returning null. The second if statement in the code covers the problem of a 1-item queue.      if (front == null)  // Happens with a 1-item queue.
         rear = null;
69
Q

Writing generic doubly linked list code

A

The following code shows the essential structure of a generic doubly linked list. Note the following:

The list element type is E.
The node type is Node Note that we could optionally use Node<>T. Using a different formal parameter name, T, for the node type prevents shadowing the list element type, E.
The null constructor creates an empty list.
The other constructor has a parameter type of E, which matches the list element type.

70
Q

Removing an item from a doubly linked list

A

The process for removing an item from a linked list is straightforward: travel down the list until you find the item, then set the link from the previous node to point to the next node, and set the link from the next node to point to the previous one. Since each node has two links, there is no need to carry a pair of pointers down the list and there is no need to look ahead.

public void remove(E item) {
Node p = head;
while (p != null && !p.data.equals(item)) { // Find the item first
p = p.next;
}
if (p != null) { // The item is in the list and p points to it.
if (p.next != null) // Fix the previous link on the next node.
p.next.previous = p.previous;
if (p.previous != null) // Fix the next link on the previous node.
p.previous.next = p.next;
if (p == head) // Take care of the special first node.
head = head.next;
}
}

71
Q

Inserting a new item after a given item in a doubly linked list

A
public void insertAfter(E newItem, E givenItem) {
      Node p = head;
      while (p != null &amp;&amp; !p.data.equals(givenItem)) { // Find the item first  
         p = p.next;
      }
      if (p == null)
         addToFront(newItem);
      else {
         Node newNode = new Node(newItem, p, p.next);
         if (p.next != null)
            p.next.previous = newNode;
         p.next = newNode;
      }
   }