Loading...

PPT – Stacks and Linked Lists PowerPoint presentation | free to download - id: 6fcda3-MWRiO

The Adobe Flash plugin is needed to view this content

Stacks and Linked Lists

Abstract Data Types (ADTs)

- An ADT is an abstraction of a data structure that

specifies - Data stored
- Operations on the data
- Error conditions associated with operations

Abstract Data Types (ADTs)

- An ADT is an abstraction of a data structure that

specifies - Data stored
- Operations on the data
- Error conditions associated with operations

- Example Registering for classes
- The data stored are the courses in your schedule
- The operations supported are
- Register(course)
- Unregister(course)
- ForceRequest(course)
- Error conditions
- Registering for multiple classes meeting at the

same time

Stacks

Stacks

- Stacks store arbitrary objects (Pez in this case)

Stacks

- Stacks store arbitrary objects (Pez in this case)
- Operations
- push(e) inserts an element to the top of the

stack

Stacks

- Stacks store arbitrary objects (Pez in this case)
- Operations
- push(e) inserts an element to the top of the

stack

Stacks

- Stacks store arbitrary objects (Pez in this case)
- Operations
- push(e) inserts an element to the top of the

stack - pop() removes and returns the top element of

the stack

Stacks

- Stacks store arbitrary objects (Pez in this case)
- Operations
- push(e) inserts an element to the top of the

stack - pop() removes and returns the top element of

the stack

Stacks

- Stacks store arbitrary objects (Pez in this case)
- Operations
- push(e) inserts an element to the top of the

stack - pop() removes and returns the top element of

the stack

Stacks

- Stacks store arbitrary objects (Pez in this case)
- Operations
- push(e) inserts an element to the top of the

stack - pop() removes and returns the top element of

the stack - top() returns a reference to the top element of

the stack, but doesnt remove it

Stacks

- Stacks store arbitrary objects (Pez in this case)
- Operations
- push(e) inserts an element to the top of the

stack - pop() removes and returns the top element of

the stack - top() returns a reference to the top element of

the stack, but doesnt remove it - Optional operations
- size() returns the number of elements in the

stack - empty() returns a bool indicating if the stack

contains any objects

Stack Exceptions

- Attempting to execute an operation of ADT may

cause an error condition called an exception - Exceptions are said to be thrown by an

operation that cannot be executed - In the Stack ADT, pop and top cannot be performed

if the stack is empty - Attempting to execute pop or top on an empty

stack throws an EmptyStackException

Exercise Stacks

- Describe the output and final structure of the

stack after the following operations - Push(8)
- Push(3)
- Pop()
- Push(2)
- Push(5)
- Pop()
- Pop()
- Push(9)
- Push(1)

Applications of Stacks

- Direct applications
- Page-visited history in a Web browser
- Undo sequence in a text editor
- Saving local variables when one function calls

another, and this one calls another, and so on. - Indirect applications
- Auxiliary data structure for algorithms
- Component of other data structures

C Run-time Stack

main() int i i 5 foo(i) foo(int j)

int k k j1 bar(k) bar(int m)

- The C run-time system keeps track of the chain

of active functions with a stack - When a function is called, the run-time system

pushes on the stack a frame containing - Local variables and return value
- Program counter, keeping track of the statement

being executed - When a function returns, its frame is popped from

the stack and control is passed to the method on

top of the stack

bar PC 1 m 6

foo PC 3 j 5 k 6

main PC 2 i 5

Array-based Stack

Algorithm size() return t 1 Algorithm

empty() return size () 0 Algorithm

pop() if empty() then throw EmptyStackException

else t ? t ? 1 return St 1

- A simple way of implementing the Stack ADT uses

an array - We add elements from left to right
- A variable keeps track of the index of the top

element

S

0

1

2

t

Array-based Stack (cont.)

- The array storing the stack elements may become

full - A push operation will then throw a

FullStackException - Limitation of the array-based implementation
- Not intrinsic to the Stack ADT

Algorithm push(e) if t S.length ? 1

then throw FullStackException else t ? t

1 St ? e

Performance and Limitations (array-based

implementation of stack ADT)

- Performance
- Let n be the number of elements in the stack
- The space used is O(n)
- Each operation runs in time O(1)
- Limitations
- The maximum size of the stack must be defined a

priori , and cannot be changed - Trying to push a new element into a full stack

causes an implementation-specific exception

Growable Array-based Stack

- In a push operation, when the array is full,

instead of throwing an exception, we can replace

the array with a larger one - How large should the new array be?
- incremental strategy increase the size by a

constant c - doubling strategy double the size

Algorithm push(o) if t S.length ? 1 then A ?

new array of size for i ? 0 to t do

Ai ? Si S ? A t ? t 1 St ? o

Comparison

- We compare the incremental strategy and the

doubling strategy by analyzing the total time

T(n) needed to perform a series of n push

operations - Assume that we start with an empty stack

represented by an array of size 1 - We call amortized time of a push operation the

average time taken by a push over the series of

operations, i.e., T(n)/n

Incremental Strategy Analysis

- We replace the array k n/c times
- The total time T(n) of a series of n push

operations is proportional to - n c 2c 3c 4c kc
- n c(1 2 3 k)
- n ck(k 1)/2
- Since c is a constant, T(n) is O(n k2) O(n2)
- The amortized time of a push operation is O(n)

Doubling Strategy Analysis

- We replace the array k log2 n times
- The total time T(n) of a series of n push

operations is proportional to - n 1 2 4 8 2k
- n 2k 1 -1 3n -1
- T(n) is O(n)
- The amortized time of a push operation is O(1)

Stack Interface in C

template ltclass Typegtclass Stack public

int size() bool isEmpty() Type

top() throw(EmptyStackException) void

push(Type e) Type pop()

throw(EmptyStackException)

- Requires the definition of class

EmptyStackException - Most similar STL construct is vector

Array-based Stack in C

template ltclass Typegt class ArrayStack private

int capacity // stack capacity Type S //

stack array int t // top of stack public

ArrayStack(int c) capacity(c) S new

Type capacity t -1 bool

isEmpty() return t lt 0 Type pop()

throw(EmptyStackException) if ( isEmpty (

) ) throw EmptyStackException(Popping

from empty stack) return S t--

// (other functions omitted)

Singly Linked List

- A singly linked list is a structure consisting of

a sequence of nodes - A singly linked list stores a pointer to the

first node (head) and last (tail) - Each node stores
- element
- link to the next node

next

node

elem

tail

head

?

Leonard

Sheldon

Howard

Raj

Singly Linked List Node in C

template ltclass Typegtclass SLinkedListNode

public Type elem SLinkedListNodeltTypegt

next

next

node

elem

?

Leonard

Sheldon

Howard

Raj

Singly Linked List

- A singly linked list is a structure consisting of

a sequence of nodes - Operations
- insertFront(e) inserts an element on the front

of the list - removeFront() returns and removes the element at

the front of the list - insertBack(e) inserts an element on the back of

the list - removeBack() returns and removes the element at

the end of the list

Inserting at the Front

- Allocate a new node
- Have new node point to old head
- Update head to point to new node

head

tail

?

Leonard

Sheldon

Howard

Raj

Inserting at the Front

- Allocate a new node
- Have new node point to old head
- Update head to point to new node

head

tail

?

?

Leonard

Sheldon

Howard

Raj

Penny

Inserting at the Front

- Allocate a new node
- Have new node point to old head
- Update head to point to new node

head

tail

?

Leonard

Sheldon

Howard

Raj

Penny

Inserting at the Front

- Allocate a new node
- Have new node point to old head
- Update head to point to new node

tail

head

?

Leonard

Sheldon

Howard

Raj

Penny

Inserting at the Front

- Allocate a new node
- Have new node point to old head
- Update head to point to new node

head

tail

?

?

Inserting at the Front

- Allocate a new node
- Have new node point to old head
- Update head to point to new node

head

tail

?

?

?

Raj

Inserting at the Front

- Allocate a new node
- Have new node point to old head
- Update head to point to new node
- If tail is NULL, update tail to point to the head

node

head

tail

?

Raj

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

Leonard

Sheldon

Howard

Raj

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

Leonard

Sheldon

Howard

Raj

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

Leonard

Sheldon

Howard

Raj

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

Leonard

Sheldon

Howard

Raj

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

Sheldon

Howard

Raj

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

Sheldon

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

?

Sheldon

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

?

Sheldon

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node

head

tail

?

?

Sheldon

Removing at the Front

- Update head to point to next node in the list
- Return elem of previous head and delete the node
- If head is NULL, update tail to NULL

head

tail

?

?

Inserting at the Back

- Allocate a new node
- If tail is NULL, update head and tail to point to

the new node otherwise - Have the old tail point to the new node
- Update tail to point to new node

head

tail

?

Leonard

Sheldon

Howard

Inserting at the Back

- Allocate a new node
- If tail is NULL, update head and tail to point to

the new node otherwise - Have the old tail point to the new node
- Update tail to point to new node

head

tail

?

?

Leonard

Sheldon

Howard

Raj

Inserting at the Back

- Allocate a new node
- If tail is NULL, update head and tail to point to

the new node otherwise - Have the old tail point to the new node
- Update tail to point to new node

head

tail

?

Leonard

Sheldon

Howard

Raj

Inserting at the Back

- Allocate a new node
- If tail is NULL, update head and tail to point to

the new node otherwise - Have the old tail point to the new node
- Update tail to point to new node

head

tail

?

Leonard

Sheldon

Howard

Raj

Removing at the Back

- No efficient way of doing so (O(n))
- Typically would not use a singly linked-list if

this operation is commonly used

head

tail

?

Leonard

Sheldon

Howard

Raj

Stack with a Singly Linked List

- We can implement a stack with a singly linked

list - The top element of the stack is the first node of

the list - The space used is O(n) and each operation of the

Stack ADT takes O(1) time

nodes

t

?

top

elements

Stack Summary

- Stack Operation Complexity for Different

Implementations

Array Fixed-Size Array Expandable (doubling strategy) Singly Linked List

Pop() O(1) O(1) O(1)

Push(o) O(1) O(n) Worst Case O(1) Best Case O(1) Average Case O(1)

Top() O(1) O(1) O(1)

Size(), isEmpty() O(1) O(1) O(1)

Queues

Queues

- Queues store arbitrary objects
- Insertions are at the end of the queue and

removals are at the front of the queue - Main queue operations
- enqueue(e) inserts an element at the end of the

queue - dequeue() removes and returns the element at the

front of the queue

- Auxiliary queue operations
- front() returns the element at the front without

removing it - size() returns the number of elements stored
- isEmpty() returns a boolean value indicating if

there are no elements in the queue - Exceptions
- Attempting to execute dequeue or front on an

empty queue throws an EmptyQueueException

Exercise Queues

- Describe the output and final structure of the

queue after the following operations - enqueue(8)
- enqueue(3)
- dequeue()
- enqueue(2)
- enqueue(5)
- dequeue()
- dequeue()
- enqueue(9)
- enqueue(1)

Applications of Queues

- Direct applications
- Waiting lines
- Access to shared resources (e.g., printer)
- User input in a game
- Indirect applications
- Auxiliary data structure for algorithms
- Component of other data structures

Array-based Queue

- Use an array of size N in a circular fashion
- Two variables keep track of the front and rear
- f index of the front element
- r index immediately past the rear element
- Array location r is kept empty

normal configuration

wrapped-around configuration

Queue Operations

- We use the modulo operator (remainder of division)

Algorithm size() return (N - f r) mod

N Algorithm isEmpty() return (f r)

Queue Operations (cont.)

Algorithm enqueue(o) if size() N ? 1

then throw FullQueueException else Qr ?

o r ? (r 1) mod N

- Operation enqueue throws an exception if the

array is full - This exception is implementation-dependent

Queue Operations (cont.)

Algorithm dequeue() if isEmpty() then throw

EmptyQueueException else o ? Qf f ? (f

1) mod N return o

- Operation dequeue throws an exception if the

queue is empty - This exception is specified in the queue ADT

Performance and Limitations - array-based

implementation of queue ADT

- Performance
- Let n be the number of elements in the queue
- The space used is O(n)
- Each operation runs in time O(1)
- Limitations
- The maximum size of the queue must be defined a

priori , and cannot be changed - Trying to enqueue a new element into a full queue

causes an implementation-specific exception

Growable Array-based Queue

- In an enqueue operation, when the array is full,

instead of throwing an exception, we can replace

the array with a larger one - Similar to what we did for an array-based stack
- The enqueue operation has amortized running time
- O(n) with the incremental strategy
- O(1) with the doubling strategy

Exercise

- Describe how to implement a queue using a

singly-linked list - Queue operations enqueue(x), dequeue(), size(),

isEmpty() - For each operation, give the running time

Queue with a Singly Linked List

- We can implement a queue with a singly linked

list - The front element is stored at the head of the

list - The rear element is stored at the tail of the

list - The space used is O(n) and each operation of the

Queue ADT takes O(1) time - NOTE we do not have the limitation of the array

based implementation on the size of the stack b/c

the size of the linked list is not fixed, I.e.,

the queue is NEVER full.

head

tail

?

Leonard

Sheldon

Howard

Raj

Informal C Queue Interface

template ltclass Typegtclass Queue public

int size() bool isEmpty() Type

front() throw(EmptyQueueException) void

enqueue(Type e) Type dequeue()

throw(EmptyQueueException)

- Informal C interface for our Queue ADT
- Requires the definition of class

EmptyQueueException - No corresponding built-in STL class

Queue Summary

- Queue Operation Complexity for Different

Implementations

Array Fixed-Size Array Expandable (doubling strategy) List Singly-Linked

dequeue() O(1) O(1) O(1)

enqueue(o) O(1) O(n) Worst Case O(1) Best Case O(1) Average Case O(1)

front() O(1) O(1) O(1)

Size(), isEmpty() O(1) O(1) O(1)

Double-Ended Queues

- The Double-Ended Queue, or Deque, ADT stores

arbitrary objects. (Pronounced deck) - Richer than stack or queue ADTs. Supports

insertions and deletions at both the front and

the end. - Main deque operations
- insertFirst(object o) inserts element o at the

beginning of the deque - insertLast(object o) inserts element o at the

end of the deque - removeFirst() removes and returns the element at

the front of the deque - removeLast() removes and returns the element at

the end of the deque

- Auxiliary deque operations
- first() returns the element at the front without

removing it - last() returns the element at the front without

removing it - size() returns the number of elements stored
- isEmpty() returns a Boolean value indicating

whether no elements are stored - Exceptions
- Attempting to execute removeFirst,removeLast,

front, or last on an empty deque throws an

EmptyDequeException

Doubly Linked List

- A doubly linked list is a structure consisting of

a sequence of nodes - A doubly linked list stores a pointer to a

special head/tail node - Each node stores
- element
- link to the prev, next node

next

prev

elem

node

tail

head

Doubly Linked List

- A doubly linked list is a structure consisting of

a sequence of nodes - A doubly linked list stores a pointer to a

special head/tail node - Each node stores
- element
- link to the prev, next node

next

prev

elem

node

head

tail

Doubly Linked List Node in C

template ltclass Typegtclass DLinkedListNode

public Type elem DLinkedListNodeltTypegt

prev, next

next

prev

elem

node

tail

head

Doubly Linked List

- A doubly linked list is a structure consisting of

a sequence of nodes - Operations
- insertFront(e) inserts an element on the front

of the list - removeFront() returns and removes the element at

the front of the list - insertBack(e) inserts an element on the back of

the list - removeBack() returns and removes the element at

the end of the list - Private operations
- add(n, e) inserts the element after the node n
- remove(n) returns and removes the element stored

in the node n

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

tail

head

Howard

Raj

Leonard

Sheldon

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

Bernadette

tail

head

Howard

Raj

Leonard

Sheldon

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

Bernadette

tail

head

Howard

Raj

Leonard

Sheldon

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

Bernadette

tail

head

Howard

Raj

Leonard

Sheldon

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

tail

head

Howard

Raj

Leonard

Sheldon

Bernadette

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

Sheldon

head

tail

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

Sheldon

head

tail

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

Sheldon

head

tail

Adding a Node

- Allocate a new node
- Have new node point to the previous and next

nodes - Update the previous and next nodes to point to

the new node

head

tail

Sheldon

Removing a Node

- Have the prev nodes next point to the next of

the current node - Have the next nodes prev point to the prev of

the current node - Delete the current node

tail

head

Howard

Raj

Leonard

Sheldon

Removing a Node

- Have the prev nodes next point to the next of

the current node - Have the next nodes prev point to the prev of

the current node - Delete the current node

tail

head

Howard

Raj

Leonard

Sheldon

Removing a Node

- Have the prev nodes next point to the next of

the current node - Have the next nodes prev point to the prev of

the current node - Delete the current node

tail

head

Howard

Raj

Leonard

Sheldon

Removing a Node

- Have the prev nodes next point to the next of

the current node - Have the next nodes prev point to the prev of

the current node - Delete the current node

tail

head

Howard

Raj

Leonard

Sheldon

Removing a Node

- Have the prev nodes next point to the next of

the current node - Have the next nodes prev point to the prev of

the current node - Delete the current node

tail

head

Raj

Leonard

Sheldon

Deque with a Doubly Linked List

- We can implement a deque with a doubly linked

list - The front element is pointed to by head
- The rear element is pointed to by tail
- The space used is O(n) and each operation of the

Deque ADT takes O(1) time

tail

head

Performance and Limitations - doubly linked list

implementation of deque ADT

- Performance
- Let n be the number of elements in the deque
- The space used is O(n)
- Each operation runs in time O(1)
- Limitations
- NOTE we do not have the limitation of the array

based implementation on the size of the deque b/c

the size of the linked list is not fixed, I.e.,

the deque is NEVER full.

Deque Summary

- Deque Operation Complexity for Different

Implementations

Array Fixed-Size Array Expandable (doubling strategy) List Singly-Linked List Doubly-Linked

removeFirst(), removeLast() O(1) O(1) O(1) removeFirst, O(n) removeLast O(1)

insertFirst(o), InsertLast(o) O(1) O(n) Worst Case O(1) Best Case O(1) Average Case O(1) O(1)

first(), last O(1) O(1) O(1) O(1)

size(), isEmpty() O(1) O(1) O(1) O(1)