CS 2223 Mar 24 2023
Classical selection: Rachmaninoff: Piano Concerto No. 2 [Kissin] (1901)
Visual Selection: Peasant Woman Binding Sheaves, Vincent Van Gogh (1889)
Live Selection: 25 or 6 to 4, Chicago (1970)
Jazz Selection: Celebrity, Charlie Parker (1950)
1 Fundamental Data Types
1.1 HW-1 LeaderBoard
Q2.1 | who | Q2.2 | who |
118147104 | Initial | 55232414 | Randa |
115140534 | Cardarelli | 55127151 | Heineman |
114337246 | Marble | 54923013 | Randa |
113997886 | Husman | 54902687 | Faulkner |
107253228 | Heineman | 54686238 | Weil-Sibal |
103811762 | Husman | 52740522 | Husman |
74305020 | Schmit | 52120875 | Foley (Recursion) |
73840264 | Alex S | 52115066 | Heineman |
73084476 | Alex Z | 51949620 | Alex Z |
70215278 | Alex S | 51904556 | Schmit |
69592275 | Schmit | 51733301 | Randa |
- | - | 51109453 | Schmit |
- | - | 49955196 | Evan S |
- | - | 49274633 | Evan S |
1.2 Review of Linked Lists
I don’t believe in mathematics. Imagination is more important than knowledge
Albert Einstein
1.3 Manipulating an ordered linked list
Review OrderedLinkedList.
1.4 Instrumenting an algorithm
When I want to generate empirical evidence on the number of times a key operation is invoked in an algorithm, I instrument the code to maintain a class attribute to hold a running accumulated count. Whenever the operation is called, just increment this value, and make it possible to retrieve it later so you can report on it.
Review Insertion to see how I did this for Insertion Sort.
1.5 Main topics in sorting
We have made some major progress in analyzing the sorting problem. From last lecture we were able to assert the Mergesort is an asymptotically optimal compare-based sorting algorithm.
We made this claim because we demonstrated that any comparison-based sorting algorithm requires ~ N log N comparisons to correctly sort an array of N elements.
The logic was based on identifying a recursive formulat that computed the number of comparisons required. We came up with the following formula that demonstrated the most number of comparisons that would be used.
C(n) <= C(n/2) + C(n/2) + N
C(n) <= 2*C(n/2) + N
Be sure you understand the logic as presented in lecture, which is supported by the book; review the class capture if that would be helpful.
1.6 Back to Fundamental Data Types
A good decision is based on knowledge and not on numbers
Plato
We are now ready to complete the last of the major data type families for this course. Much like the platonic solids from geometry, these are the fundamental building blocks for algorithms:
These data types are:
Bag (p. 121) – Use with collections of non-comparable objects. Use when you don’t care overmuch about individual retrieval of elements but rather only want to retrieve all elements one at a time.
Stack (p. 121) – Use when you want Last-in, First-out (LIFO) behavior. Can be structured to support expandable collections or can be restricted to fixed capacity.
Queue (p. 121) – Use when you want First-in, First-out (FIFO) behavior. Can be structured to support expandable collections or can be restricted to fixed capacity.
Max Priority Queue (p. 309) – Use when you want to retrieve specific element that is "largest value" or "highest priority". Can be structured to support expandable collections or can be restricted to fixed capacity. Can be augmented to support arbitrary re-classification of "value" or "priority" (IndexMinPQ (p. 320) which we will cover in few weeks).
Symbol Table (p. 363) – Use when you want to associate a value with a key.
We are going to introduce the Symbol Table type today and over the next lecture we will complete its implementation.
1.7 Symbol Table
Each symbol table has a type representing the key and a type representing the value. For example, to count word frequencies in text (p. 372) you might want to associate an Integer with a String.
Operation | Description |
put (Key key, Value value) | Associate (key,value) in table |
Value get (Key key) | retrieve value for key |
void delete (Key key) | remove (key,value) pair in table |
boolean contains (Key key) | check if table has key |
int size | return number of pairs |
boolean isEmpty | determine if empty |
To date, we have been concerned with collections for storing and retrieving individual items. Now we are contemplating an extension for storing associated pairs.
I claim that we already have the underlying data structures in place to properly implement the Symbol Table type.
1.8 Key Equality
These symbol tables are primarily concerned with testing equality of keys. When primitive data types are compared, the "==" operator is the default one used. In this case, each Key is a full Java object and we therefore assume that the Key class has an associated boolean equals (Object o) method that provides a semantic equality that goes beyond string equality.
1.9 Ordered Symbol Tables
We will begin to cover ordered symbol tables after the first exam.
1.10 Potential Implementation
We have covered enough structures to support the Symbol Table API. Today we will describe this in the context of linked lists that store additional information. This SequentialSearchST<Key, Value> implementation is from p. 375 of the book (find code in SequentialSearchST)
We have already seen how to use linked lists to store information, both ordered and unordered. The change here is to modify the structure of each node. The following defines the class and its inner Node class used to store the information.
public class SequentialSearchST<Key, Value> { int N; // number of key-value pairs Node first; // the linked list of key-value pairs // Nodes now store (key and value) class Node { Key key; Value value; Node next; public Node (Key key, Value val, Node next) { this.key = key; this.value = val; this.next = next; } } }
As you might imagine, we will build up linked lists of these (key, value) using put(key,value) operations, which only become a bit more complicated because you may be replacing a value that is already associated with key in the SequentialSearchST symbol table.
First observe that there is a useful constructor for creating Node objects from a (key, value) pair and a link to the next Node to use. Should you not wish to have the node have a next link, then simply pass null as the third parameter to this constructor.
This is a standard template you will see a lot this week:
Node n = first;
while (n != null) {
// some coden = n.next;
}
public void put(Key key, Value val) { Node n = first; while (n != null) { if (key.equals (n.key)) { n.value = val; return; } n = n.next; } // add as new node at beginning first = new Node (key, val, first); N++; }
The above while loop visits each Node in the linked list to see if it is the one whose key matches the incoming key parameter. Should there be a match, then this is a request to reassociated the new value val with this existing key, so the value associated with that node in the linked list is updated and the function returns.
Should there be no match with an existing key in the linked list, then we must add a node node. This is done, here, by making it the new first node of the linked list. This is the same behavior as you saw earlier with the Bag data type. Don’t forget to increment N which keeps track of the number of items in the linked list.
1.11 Retrieve information
The get(key) method is even simpler than the put method. You simply traverse the linked list one at a time, trying to find the node whose key value matches the key parameter. If found, then return the associated value stored by that Node otherwise return null.
public Value get(Key key) { Node n = first; while (n != null) { if (key.equals (n.key)) { return n.value; } n = n.next; } return null; // not present }
On Monday we will complete the implementation of a Symbol Table by explaining strategies for deleting a (key, value) pair from a Symbol Table.
1.12 Interview Challenge
Each Friday I will post a sample interview challenge. During most technical interviews, you will likely be asked to solve a logical problem so the company can see how you think on your feet, and how you defend your answer.
A plane with N seats is ready to allow passengers on board, and it is
indeed a full flight; every seat has been purchased. Each person has a
boarding pass that identifies the seat to sit in. When the announcement is
made to board the plane, all passengers get in line, in some random order.
The first person to board the airplane somehow loses his boarding pass as
he enters the plane, so he picks a random seat to sit in.
All other passengers have their boarding passes when they enter the
plane. If no one is sitting in their seat, they sit down in their assigned
seat. However, if someone is sitting in their seat, they choose a
random empty seat to sit in.
My question is this: What is the probability that the last person to
take a seat is sitting in their proper seat as identified by their boarding
pass?
1.13 Version : 2023/04/07
(c) 2023, George T. Heineman