0% found this document useful (0 votes)
47 views

Lecture 2: Stacks and Queues: CSE 373: Data Structures and Algorithms

This document summarizes a lecture on stacks and queues. It discusses implementing stacks and queues using arrays and linked lists. For stacks and queues, it reviews their abstract data type definitions and common operations like push, pop, and peek. It also compares the time and space complexities of accessing, inserting, and deleting elements from arrays and linked lists. Finally, it previews testing code and briefly mentions implementing dictionaries with arrays and linked lists.

Uploaded by

Tawsif
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views

Lecture 2: Stacks and Queues: CSE 373: Data Structures and Algorithms

This document summarizes a lecture on stacks and queues. It discusses implementing stacks and queues using arrays and linked lists. For stacks and queues, it reviews their abstract data type definitions and common operations like push, pop, and peek. It also compares the time and space complexities of accessing, inserting, and deleting elements from arrays and linked lists. Finally, it previews testing code and briefly mentions implementing dictionaries with arrays and linked lists.

Uploaded by

Tawsif
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 31

Lecture 2: Stacks and CSE 373: Data Structures and

Queues Algorithms

CSE 373 19 SU -- ROBBIE WEBER 1


Administrivia
Course Stuff
- Office hours are on class webpage: cs.washington.edu/373
- Piazza: https://piazza.com/class/jwcann1clfq7bn
- Add code is on Canvas (or ask a staff member)

Project 0 Live!
- Individual assignment
- 14x content review
- GitLab/IntelliJ setup
- You should have already gotten an automatic email with a link to your gitlab repo.
- Check your spam folder

Project 1 out next week, partner project


- find your own partner
- Lecture, section, piazza, office hours
Last 5-10 minutes of section will be help with gitlab/intelliJ setup (if you’re stuck bring your
laptop and get some help.)

CSE 373 19 SU -- ROBBIE WEBER 2


Q: Would you use a LinkedList or ArrayList
Warm Up implementation for each of these scenarios?
Situation #1: Write a data
ArrayList
Instructions
LinkedList
uses an Array as underlying storage uses nodes as underlying storage
structure that implements the List
ADT that will be used to store a
ArrayList<E> LinkedList<E> list of songs in a playlist. Take 3 Minutes
state state
data[]
size Node front Situation #2: Write a data 1. Introduce yourself to
behavior
get return data[index]
size
behavior structure that implements the List your neighbors 
set data[index] = value get loop until index,
ADT that will be used to store the
append data[size] = return node’s value 2. Discuss your answers
value, if out of space set loop until index, history of a bank customer’s
grow data update node’s value
insert shift values to append create new transactions. 3. Log onto Poll
make hole at index, node, update next of
data[index] = value, if last node Everywhere
out of space grow data
delete shift following
insert create new
node, loop until
Situation #3: Write a data 1. Go to
values forward index, update next structure that implements the List PollEv.com/cse373su1
size return size fields
delete loop until ADT that will be used to store the 9
0 1 2 3 4 index, skip node
order of students waiting to speak 2. OR Text CSE373Su19 to
size return size
88.6 26.1 94.4 0 0 22333 to join session,
to a TA at a tutoring center
text “1” “2” or “3” to
88.6 26.1 94.4
free space
select your answer
list

4. Get extra credit!


CSE 373 19 SU -- ROBBIE WEBER 3
Design Decisions
Situation #1: Write a data structure that implements the List ADT that will be used to store a list
of songs in a playlist.
ArrayList – I want to be able to shuffle play on the playlist
Situation #2: Write a data structure that implements the List ADT that will be used to store the
history of a bank customer’s transactions.
ArrayList – optimize for addition to back and accessing of elements
Situation #3: Write a data structure that implements the List ADT that will be used to store the
order of students waiting to speak to a TA at a tutoring center
LinkedList - optimize for removal from front
ArrayList – optimize for addition to back

CSE 373 19 SU -- ROBBIE WEBER 4


List ADT tradeoffs
 Last time: we used “slow” and “fast” to describe running times. Let’s be a little more precise.
Recall these basic Big-O ideas from 14X: Suppose our list has N elements
- If a method takes a constant number of steps (like 23 or 5) its running time is O(1)
- If a method takes a linear number of steps (like 4N+3) its running time is O(N)

For ArrayLists and LinkedLists, what is the O() for each of these operations?
- Time needed to access element:
- Time needed to insert at end (the array is full!)

What are the memory tradeoffs for our two implementations?


- Amount of space used overall
- Amount of space used per element
ArrayList<Character> myArr LinkedList<Character> myLl
0 1 2 3 4

‘h’ ‘e’ ‘l’ ‘l’ ‘o’ front ‘h’ ‘e’ ‘l’ ‘l’ ‘o’ /
CSE 373 19 SU -- ROBBIE WEBER 5
List ADT tradeoffs
 Time needed to access element:
- ArrayList: O(1) constant time ArrayList<Character> myArr
- LinkedList: O(N) linear time 0 1 2 3 4
Time needed to insert at element (the array is full!) ‘h’ ‘e’ ‘l’ ‘l’ ‘o’
- ArrayList: O(N) linear time
- LinkedList: O(N) linear time

Amount of space used overall


LinkedList<Character> myLl
- ArrayList: sometimes wasted space
- LinkedList: compact front ‘h’ ‘e’ ‘l’ ‘l’ ‘o’ /

Amount of space used per element


- ArrayList: minimal
- LinkedList: tiny extra

CSE 373 19 SU -- ROBBIE WEBER 6


Goals for Today
Review Stacks, Queues
- What are the ADTs
- How can you implement both of them with arrays and with nodes?

Basics of Testing your code.

(maybe) Review Dictionaries.


- What is the ADT
- Can we implement well with arrays and nodes?

CSE 373 19 SU - ROBBIE WEBER 7


Review: What is a Stack?
stack: A collection based on the principle of adding elements
and retrieving them in the opposite order.
- Last-In, First-Out ("LIFO") push pop, peek
- Elements are stored in order of insertion.
- We do not think of them as having indexes.
- Client can only add/remove/examine
the last element added (the "top"). top 3
2
Stack ADT
bottom 1
state
Set of ordered items supported operations:
Number of items
- push(item): Add an element to the top of stack
behavior
push(item) add item to top - pop(): Remove the top element and returns it
pop() return and remove item at - peek(): Examine the top element without removing it
top
peek() look at item at top - size(): how many items are in the stack?
size() count of items
isEmpty() count of items is 0? - isEmpty(): false if there are 1 or more items in stack, true otherwise
CSE 143 SP 17 – ZORAH FUNG 8
Implementing a Stack with an Array
Stack ADT ArrayStack<E> Big O Analysis
state state pop() O(1) Constant
Set of ordered items data[]
Number of items size
peek() O(1) Constant
behavior behavior
push data[numItems] = value, if
push(item) add item to top
out of room grow data, numItems++ size() O(1) Constant
pop() return and remove item at
pop return data[numItems - 1],
top
numItems-=1 isEmpty() O(1) Constant
peek() look at item at top
peek return data[numItems - 1]
size() count of items
size return numItems push() Don’t resize: O(1) Constant
isEmpty() count of items is 0?
isEmpty return numItems == 0 Do resize: O(N) linear

0 1 2 3
push(3)
3 45
push(4)
pop()
numItems = 2
0
1
push(5)
CSE 373 19 SU - ROBBIE WEBER 9
Implementing a Stack with Nodes
Stack ADT LinkedStack<E> Big O Analysis
state state pop() O(1) Constant
Set of ordered items Node top
Number of items size
peek() O(1) Constant
behavior behavior
push add new node at top
push(item) add item to top
numItems++ size() O(1) Constant
pop() return and remove item at
pop return and remove node at
top
top, numItems-=1 isEmpty() O(1) Constant
peek() look at item at top
peek return node at top
size() count of items
size return numItems push() O(1) Constant
isEmpty() count of items is 0?
isEmpty return numItems == 0

push(3)
front 3
push(4)
pop() numItems = 0
1
2
CSE 373 19 SU - ROBBIE WEBER 10
Review: What is a Queue?
queue: Retrieves elements in the order they were added.
- First-In, First-Out ("FIFO")
- Elements are stored in order of insertion but don't have indexes.
- Client can only add to the end of the queue, and can only
examine/remove the front of the queue.

front back
remove, peek add
1 2 3
Queue ADT
state supported operations:
Set of ordered items
Number of items - add(item): aka “enqueue” add an element to the back.
behavior - remove(): aka “dequeue” Remove the front element and return.
add(item) add item to back
remove() remove and return - peek(): Examine the front element without removing it.
item at front
peek() return item at front
- size(): how many items are stored in the queue?
size() count of items - isEmpty(): if 1 or more items in the queue returns true, false otherwise
isEmpty() count of items is 0?
CSE 373 19 SU - ROBBIE WEBER 11
Implementing a Queue with an Array
Queue ADT ArrayQueue<E> Big O Analysis
state state remove() O(1) Constant
Set of ordered items data[]
Number of items numItems
peek() O(1) Constant
front index
behavior back index
add(item) add item to back size() O(1) Constant
remove() remove and return behavior
add – data[back] = value, if out of
item at front
room grow data, back++, numItems++ isEmpty() O(1) Constant
peek() return item at front
remove – return data[front],
size() count of items
numItems-=1, front++ add() Don’t resize: O(1) Constant
isEmpty() count of items is 0?
peek – return data[front] Do resize: O(N) linear
size – return numItems
isEmpty – return numItems == 0

0 1 2 3 4
add(5) 5 8 9
add(8)
numItems = 3
2
1
0
add(9) front = 01
remove() back = 0
2
1 CSE 373 19 SU - ROBBIE WEBER 12
Implementing a Queue with an Array
> Wrapping Around
front back
add(7)
add(4) 0 1 2 3 4

add(1) 4 5 9 2 7

front back numItems = 5


3
4

0 1 2 3 4 5 6 7 8 9

5 9 2 7 4 1
CSE 373 19 SU - ROBBIE WEBER 13
Implementing a Queue with Nodes
Queue ADT LinkedQueue<E> Big O Analysis
state state remove() O(1) Constant
Set of ordered items Node front
Number of items Node back
peek() O(1) Constant
numItems
behavior
add(item) add item to back size() O(1) Constant
remove() remove and return behavior
add – add node to back, numItems++
item at front
remove – return and remove node at isEmpty() O(1) Constant
peek() return item at front
size() count of items front, numItems--
isEmpty() count of items is 0? peek – return node at front add() O(1) Constant
size – return numItems
isEmpty – return numItems == 0

numItems = 2
0
1

add(5)
add(8) front 5 8

remove() back
CSE 373 19 SU - ROBBIE WEBER 14
Multiple Levels of Design Decisions
Implementation Details
- Do we overwrite old values with null or do we leave the garbage value?
- Do we validate input and throw exceptions or just wait for the code to fail?

Data structure choice


- Do we use a LinkedList or an ArrayList?
- Do we use a Node-based queue implementation or an array-based implementation?

Choice of ADT
- Which of the ADTs that we’ve seen is the best fit?

(We’ll see other kinds of design decisions later in the quarter).

CSE 373 19 SU - ROBBIE WEBER 15


Design Decisions
Take 3 Minutes

Discuss with your neighbors: For each scenario select the appropriate ADT and implementation
to best optimize for the given scenario.
Situation #1: You are writing a program to manage a todo list with a specific approach to tasks.
This program will order tasks for so that the most recent task is addressed first. You don’t want to
risk a long delay between submission of an item and its appearance.
Stack – First in Last out
Nodes – make addition and removal of tasks very easy
Situation #2: You are writing a program to schedule jobs sent to a laser printer. The laser printer
should process these jobs in the order in which the requests were received. The printer has very
limited memory.
Queue – First in First out
Array – want to save the extra pointers to fit in our limited space

CSE 373 19 SU - ROBBIE WEBER 16


Testing Your Code

CSE 373 19 SU - ROBBIE WEBER 17


Testing: Why are we doing this?
The ability to test your own code is integral to an understanding of data structures.
- Differentiating between ADT requirements and design decisions you made.
- Coming up with test cases is one of the best ways to understand data structures more deeply
- What cases will cause certain implementations to slow down?
- How long do I expect certain operations to take?
- What edge cases are there in the definition?
- Where else might I find bugs?

In the real world, coding projects don’t come with their own tests.
- You have to write your own.

You might be frustrated with us at some point for not giving you test cases.
- I understand. I was frustrated with my data structures professor when she didn’t give us tests.
- Learning to test your own code is integral to maturing as a computer scientist.
- We’re always tweaking things to make this as painless as we can.

CSE 373 19 SU - ROBBIE WEBER 18


Testing
Today: Strategies for generating tests. Ways to think about testing.
Thursday: Activity to practice our particular testing framework

CSE 373 19 SU - ROBBIE WEBER 19


Testing
Computers don’t make mistakes- people do!
“I’m almost done, I just need to make sure it works”
– Naive 14Xers

Software Test: a separate piece of code that exercises the code you are assessing by providing
input to your code and finishes with an assertion of what the result should be.

1. Isolate - break your code into small modules


2. Build in increments - Make a plan from simplest to most complex cases
3. Test as you go - As your code grows, so should your tests

CSE 373 19 SU - ROBBIE WEBER 20


Types of Tests
Black Box
- Behavior only – ADT requirements
- From an outside point of view
- Does your code uphold its contracts with its users?
- Performance/efficiency

White Box
- Includes an understanding of the implementation
- Written by the author as they develop their code
- Break apart requirements into smaller steps
- “unit tests” break implementation into single assertions

CSE 373 19 SU - ROBBIE WEBER 21


What to test?
Expected behavior
- The main use case scenario
- Does your code do what it should given friendly conditions?

Forbidden Input
- What are all the ways the user can mess up?

Empty/Null
- Protect yourself!
- How do things get started?
- 0, -1, null, empty collections

Boundary/Edge Cases
- First items
- Last item
- Full collections (resizing)

Scale
- Is there a difference between 10, 100, 1000, 10000 items?

CSE 373 19 SU - ROBBIE WEBER 22


Testing Strategies
You can’t test everything
- Break inputs into categories
- What are the most important pieces of code?

Test behavior in combination


- Call multiple methods one after the other
- Call the same method multiple times

Trust no one!
- How can the user mess up?

If you messed up, someone else might


- Test the complex logic

CSE 373 19 SU - ROBBIE WEBER 23


5 Minutes
Thought Experiment
Discuss with your neighbors: Imagine you are writing an implementation of the List interface that stores
integers in an Array. What are some ways you can assess your program’s correctness in the following cases:
Expected Behavior Boundary/Edge Cases
- Create a new list
- Add 1 item to an empty list
- Add some amount of items to it
- Remove a couple of them - Set an item at the front of the list
- Set an item at the back of the list
Forbidden Input
- Add a negative number Scale
- Add duplicates - Add 1000 items to the list
- Add extra large numbers - Remove 100 items in a row
- Add something to index 10 of a size 3 list
- Set the value of the same item 50 times
Empty/Null
- Call remove on an empty list
- Add to a null list
- Call size on an null list

CSE 373 19 SU - ROBBIE WEBER 24


JUnit
JUnit: a testing framework that works with IDEs to give you a special GUI when testing your
code
@Test
public void myTest() {
MyArrayList<String> basicAl = new MyArrayList<String>();
basicAl.append(“373 Rocks”);
assertThat(basicAl.get(0), is(“373 Rocks”));
}

Assertions:
- assertThat(thingYoureTesting, is(ExpectedResult)) is most common. Calls .equals() method
- May write your own helper methods here to check that internal state is identical.
- Other assertions exist; see official documentation, or our documentation on the webpage.

More: https://junit.org/junit5/docs/5.0.1/api/org/junit/jupiter/api/Assertions.html CSE 373 19 SU - ROBBIE WEBER 25


Review: Generics public class Box {
private Object object;
public void set(Object object) {
// a parameterized (generic) class this.object = object;
public class name<TypeParameter> { }
public Object get() {
... return object;
} }
}

- Forces any client that constructs your object to supply a type


- Don't write an actual type such as String; the client does that
- Instead, write a type variable name such as E (for "element") or T (for
"type")
- You can require multiple type parameters separated by commas public class Box<T> {
private T t;
public void set(T t) {
this.t = t;
- The rest of your class's code can refer to that type by name }
public T get() {
return t;
}
}

More details: https://docs.oracle.com/javase/tutorial/java/generics/types.html


CSE 373 19 SU - ROBBIE WEBER 26
Dictionaries

CSE 373 19 SU - ROBBIE WEBER 27


Dictionaries (aka Maps)
Every Programmer’s Best Friend
You’ll use one in every single programming project.
- Because I don’t think we could really design an interesting project that doesn’t use one.

CSE 373 19 SU - ROBBIE WEBER 28


Review: Maps key
“at"
value
43
key value

key value “in" 37


“you" 22
map: Holds a set of unique keys and a collection of key value

values, where each key is associated with one value. “the" 56

- a.k.a. "dictionary"

map.get("the") 56
supported operations:
Dictionary ADT
- put(key, value): Adds a given item into
state collection with associated key, if the
Set of items & keys map previously had a mapping for the
Count of items given key, old value is replaced
behavior
put(key, item) add item to - get(key): Retrieves the value mapped to
collection indexed with key
get(key) return item associated
the key
with key - containsKey(key): returns true if key is
containsKey(key) return if key
already in use
already associated with value in map,
remove(key) remove item and false otherwise
associated key
size() return count of items
- remove(key): Removes the given key
and its mapped value
CSE 373 19 SU - ROBBIE WEBER 29
2 Minutes
Implementing a Dictionary with an Array
Dictionary ADT ArrayDictionary<K, V> Big O Analysis
state state put() O(N) linear
Set of items & keys Pair<K, V>[] data
Count of items
get() O(N) linear
behavior behavior
containsKey() O(N) linear
put create new pair, add to
put(key, item) add item to next available spot, grow
collection indexed with key array if necessary
get(key) return item associated get scan all pairs looking remove() O(N) linear
with key for given key, return
containsKey(key) return if key associated item if found size() O(1) constant
already in use containsKey scan all pairs,
remove(key) remove item and return if key is found
associated key remove scan all pairs,
size() return count of items replace pair to be removed
with last pair in collection
size return count of items in
put(‘a’, 1) dictionary

put(‘b’, 2)
put(‘c’, 3) 0 1 2 3
put(‘d’, 4)
97)
(‘a’, 1) (‘b’, 2) (‘c’, 3) (‘d’, 4)
remove(‘b’)
put(‘a’, 97) CSE 373 19 SU - ROBBIE WEBER 30
2 Minutes
Implementing a Dictionary with Nodes
Dictionary ADT LinkedDictionary<K, V> Big O Analysis
state state put() O(N) linear
Set of items & keys front
Count of items size
get() O(N) linear
behavior behavior
containsKey() O(N) linear
put if key is unused, create new with
put(key, item) add item to
pair, add to front of list, else
collection indexed with key
replace with new value
get(key) return item associated
get scan all pairs looking for given remove() O(N) linear
with key
key, return associated item if found
containsKey(key) return if key
containsKey scan all pairs, return if size() O(1) constant
already in use
key is found
remove(key) remove item and
remove scan all pairs, skip pair to be
associated key
removed
size() return count of items
size return count of items in
dictionary

put(‘a’, 1)
put(‘b’, 2) front

put(‘c’, 3)
put(‘d’, 4)
remove(‘b’) ‘d’ 4 ‘c’ 3 ‘b’ 2 ‘a’ 97
1
put(‘a’, 97) CSE 373 19 SU - ROBBIE WEBER 31

You might also like