Lecture 06: Relationships, Sets, and Running Times

Overview

• Lists
• Deques
• Queues
• Stacks
3. Implementing Sets
4. Running Time Assumptions

• List
• Deque
• Stack
• Queue

Simulating Operations

Question. Given a List, how can you simulate a Deque?

• addFirst?
• addLast?
• removeFirst?

public class ASLDeque<E> implements SimpleDeque<E> {
private SimpleList<E> list = new ArraySimpleList<E>();

public int size() { return list.size(); }

public boolean isEmpty() { return list.isEmpty(); }

public E removeFirst() { return list.remove(0); }

public E peekFirst() { return list.get(0); }

public E removeLast() { return list.remove(list.size() - 1); }

public E peekLast() { return list.get(list.size() - 1); }
}


Question

If we can always use a List, why would we ever want just a stack/queue/deque?

Designing for Efficency

Use the simplest ADTs that provides the required functionality to solve a problem

• a straightforward implementation of a simple ADT is often more efficient than a sophisticated implementation of a more general ADT

See, e.g., Assignments 2 and 3

Sets

Sets

A set is a collection of unique elements

• any element appears only once in the set

• no order (index) associated with elements

Sets of numbers:

Basic Operations:

• determine size of set (number of distinct elements)
• remove an element from set if present
• find and return an element in set, if present

Set Example

Example $$\texttt{set} = \{2, 3, 4, 7, 11\}$$

• set.add(3)
• set.add(5)
• set.remove(4)
• set.find(7)
• set.find(8)

SimpleUSet Interface

public interface SimpleUSet<E> {
int size();

boolean isEmpty();

E remove(E x);

E find(E x);
}


Question 1

How can we implement a SimpleUSet using a SimpleList?

public interface SimpleList<E> {
int size();
boolean isEmpty();
E get(int i);
void set(int i, E x);
E remove(int i);
}

public interface SimpleUSet<E> {
int size();
boolean isEmpty();
E remove(E x);
E find(E x);
}


How to Add to a Set?

public class ListSimpleUSet<E> implements SimpleUSet<E> {
private SimpleList<E> list;

...

...
}
}


How to Remove?

public class ListSimpleUSet<E> implements SimpleUSet<E> {
private SimpleList<E> list;

...

public E remove(E x) {
...
}
}


How to Find?

public class ListSimpleYSet<E> implements SimpleUSet<E> {
private SimpleList<E> list;

...

public E find(E x) {
...
}
}


Question 2

Which SimpleList implementation would be more efficient to use in ListSimpleUSet?

• ArraySimpleList
• LinkedSimpleList

Will there be a big difference in performance?

Consider add operation

• What SimpleList operations does add use?
• How many such operations does operations does add require?
• How efficient is each operation for…
• ArraySimpleList?
• LinkedSimpleList?

Testing our ListSimpleUSet

Make ListSimpleUSet.java

• constructor allows user to choose SimpleList implementation

Compare ArraySimpleList vs LinkeSimpleList performance

Remark on == vs .equals()

Consider the following code:

Integer i = new Integer(10);
Integer j = new Integer(10);

if (i == j) {
System.out.println("They're the same!");
} else {
System.out.println("They're not the same!");
}


What does it print?

Integer i = new Integer(10);
Integer j = new Integer(10);

if (i.equals(j)) {
System.out.println("They're the same!");
} else {
System.out.println("They're not the same!");
}


Question

What is the difference between i == j and i.equals(j)?

Terminology

• i == j connotes literal equality
• i and j refer to the same object
• i.equals(j) connotes semantic equivalence
• i and j behave in the same way

Usage

When defining a new class, by default == and .equals have the same effect:

• both are true only when their arguments refer to the same object instance

We can override the default implementation to make equals method do something different

• E.g., for Integers, i.equals(j) if i and j store the same int value

For SimpleUSet<E>

Must be sure to use equals method, not ==!

SimpleUSet<Integer> set;


Result should be that set contains only one element whose value is 2.

Find and Remove

find and remove return instances stored by the set

E.g., this:

public E find(E x) {
E y;
for(int i = 0; i < list.size(); ++i) {
y = list.get(i);
if (x.equals(y)) {
return y;
}
return null;
}


Not this:

public E find(E x) {
E y;
for(int i = 0; i < list.size(); ++i) {
y = list.get(i);
if (x.equals(y)) {
return x;
}
return null;
}