Title: List, Stack, Queue
1List, Stack, Queue
2List
- It is about putting things in a sequence.
- Example A1,A2,A3,,An
first
last
3What can we do with a list
- Find find a specified member.
- Insert insert a new member at a specified
position. - findKth return the kth element.
- Remove remove a specified element from list.
- Head return the first member.
- Tail return the list without its first member.
- Append combine 2 lists.
4What if we create a list from an array?
- Do not forget that an array needs us to specify
its length. - Find -gt O(n)
- Because we need to search from the first element
of the list. - findKth O(1)
- We can use index to find the kth element
directly. - Insert and remove may take a long time
- Because all members may be shifted.
5Linked list
node
- Find -gt O(n)
- because we still need to start at the biginning
of the list. - findKth(i) -gt O(i)
- Because we cant use array index any more.
6Linked list (cont.)
- Deletion is easier (no need to shift members)
- We only need to point reference over to the next
node.
The original list
When A2 is removed.
7Linked list (cont 2.)
- Insertion is also similar.
8Insert -gt a small problem
- Inserting the first member is different from
inserting others. - No other node pointing to x.
- Need the former A1 reference to point to x.
The code needs to be different from other
insertions.
9We can avoid such special case.
- We have a dummy node (or header) at the front of
the list. - With this solution, every node will have a node
in front, therefore all codes will be the same.
10Code node
- class ListNode
-
- // Constructors
- ListNode( Object theElement )
-
- this( theElement, null )
-
- ListNode( Object theElement, ListNode n )
-
- element theElement
- next n
-
Point to n.
11// Friendly data accessible by other package
routines Object element
ListNode next
Instance variables
12List iterator
- Is an object pointing to a node we are interested
in. - Why do we have to write this class separate from
list? - We can keep an interested node in our list
anyway, right? - Its because
- If we use iterator, we can keep a general form of
list separate from any interested node.
13Code iterator
public class LinkedListItr
ListNode current //interested position
/ _at_param theNode any node in the
list / LinkedListItr( ListNode
theNode ) current
theNode
14- / see if current has passed the last
element of the list. - _at_return true if current is null
- /
- public boolean isPastEnd( )
-
- return current null
-
- /
- _at_return item stored in current, or
null if - current is not in a list.
- /
- public Object retrieve( )
-
- return isPastEnd( ) ? null
current.element -
-
15- /
- move current to the next position in
the list. - If current is null, do nothing.
- /
- public void advance( )
-
- if( !isPastEnd( ) )
- current current.next
-
-
-
16Code linked list
- public class LinkedList
-
- private ListNode header
- public LinkedList( )
-
- header new ListNode( null )
-
- public boolean isEmpty( )
-
- return header.next null
-
17- / make the list empty./
- public void makeEmpty( )
-
- header.next null
-
- /
- return iterator that points to the
header node. - /
- public LinkedListItr zeroth( )
-
- return new LinkedListItr( header )
-
-
18- / return iterator that points to the
node next to header (can be null if the list is
empty.)/ - public LinkedListItr first( )
-
- return new LinkedListItr( header.next
) -
- / insert a new node following the position
pointed to by p. - _at_param x item to be in the new node.
- _at_param p iterator of the position
before the new node. - /
- public void insert( Object x,
LinkedListItr p ) -
- if( p ! null p.current ! null )
- p.current.next new ListNode( x,
p.current.next ) -
-
19- /
- _at_param x object that we want to find.
- _at_return iterator that points to the
first node that has x. - If x is not in the list, the iterator
points to null. -
- /
- public LinkedListItr find( Object x )
-
- / 1/ ListNode itr header.next
- / 2/ while( itr ! null
!itr.element.equals( x ) ) - / 3/ itr itr.next
- / 4/ return new LinkedListItr( itr )
-
20- /
- return iterator that points to a node
before the first - node that has x. If there is no x in the list,
return iterator that points to the last node in
the list. - /
- public LinkedListItr findPrevious( Object
x ) -
- / 1/ ListNode itr header
- / 2/ while( itr.next ! null
!itr.next.element.equals( x ) ) - / 3/ itr itr.next
- / 4/ return new LinkedListItr( itr )
-
21- /
- remove the first node with x from the
list. - _at_param x is the item to be removed
from the list. - /
- public void remove( Object x )
-
- LinkedListItr p findPrevious( x )
- if( p.current.next ! null ) //mean x
is found because -
// p is not the last member. -
- p.current.next p.current.next.next
- //move reference
-
//over x -
-
22- public static void printList( LinkedList theList
) -
- if( theList.isEmpty( ) )
- System.out.print( "Empty list" )
- else
-
- LinkedListItr itr
theList.first( ) - for( !itr.isPastEnd( )
itr.advance( ) ) - System.out.print(
itr.retrieve( ) " " ) -
- System.out.println( )
-
23Doubly linked list
- Node has extra instance variable
- Previous point to the node in front. This works
the same way as next, but pointing in a different
direction. - We can search both ways.
- Additional time to change pointers.
24Insert doubly linked list
25Remove doubly linked list
26Circular Linked list
- Last node points to the first node.
- no dummy node needed.
- We can even make it into a doubly linked list.
27linked list example
- Let us want to store a polynomial
- We can use array, using index i to store the
coefficient of
28Using array to store polynomial
When adding polynomials
- The answer comes from the addition of
corresponding slots, as shown.
29Using array to store polynomial (2)
multiplying two polynomial
- Each slot multiplies every slot of the other
polynomial, then all results are added. - If there are many terms with 0 coefficient, there
will be so many multiplication with 0. - Waste of time.
30use linked list instead
- Reduce the number of 0. Save space.
- Example 5x7511x1258
5
8
11
75
125
0
header
coefficient
Power of x
31Skip list
- A node can have more than one next pointers.
- The extra pointers point to other parts of the
list.
- In this example, every node has a pointer to
next. - A node in a position that is divisible by two
will also have a pointer pointing to the next
node with that quality. - Same for a node in a position divisible by four.
32Skip list problem
- Inserting and removing an element will cause all
pointers structure to be changed. - Too hard to do.
- Usually only the number of pointers for each
level is enforced. - Example a 20 node list.
- Level 0 gt 20 nodes
- Level 1 gt 10 nodes
- Level 2 -gt 5 nodes
- Level 3 -gt 2 nodes
33Skip list problem (cont)
- The number of nodes in the example
- Level 3 -gt 2 nodes
- Level 2 -gt 5-2 3 nodes
- Level 1 -gt 10-2-3 5 nodes
- Level 0 -gt 20-5-3-2 10 nodes
- When adding a new node, random a number between 1
and 20. - 1 to 10 -gt add the node with link level 0.
- 11 to 15 -gt add the node with link level 1.
- And so on.
34Self-Organizing List
- Put the data just viewed in front of the list, or
- Swap the node just viewed with a node in front,
or - Putting elements according to access frequency,
or - Use a specific ordering scheme, such as
alphabetically ordered. - Good for searching.
- If we cannot find an element within a certain
number of steps, we will know that the element is
not in a list.
35Self-Organizing List(cont.)
- Adam Drozdek (he has a book on data structure)
found that - Putting the most recently viewed data in front of
a list yields the same speed as ordering the list
by data access frequency. - Faster than
- swapping the node just viewed with a node in
front. - Using a specific ordering scheme.
36Multilist or Sparce Matrix
- Example data of all students and all subjects
taught by our university. We must be able to - Find all subjects a particular student is taking.
- Find all students enroll in a particular subject.
- We can use a 2D array to create a table of
students and subjects. - But there will be lots of empty spaces.
- A medical student and an engineering student
surely enroll in different subjects. - We can fix this problem by making a 2D list.
37(No Transcript)
38graph
B
C
A
D
E
B E A C B D E
Sparce table
Node directory
39stack
- Are divided into levels. We can only insert and
remove things one way. - (LIFO last in, first out)
- What can we do
- Push put an object at the top.
- Pop remove the top most element.
- Top return the top element without removing
anything.
A
B
C
?
40Making a stack from list
- Push insert new object next to header.
- Pop remove object next to header.
- If the list is originally empty, we can
- Do nothing, or
- throw exception.
- Top return an element in the node next to
header.
41Stack code
- Modified from linked list
- For simplicity, we do not have a header in this
example. - We can make a stack even though we do not have
header. - public class StackFromLinkedList
- private ListNode top
- public StackFromLinkedList( )
- top null
-
42- /
- _at_return always return false.
- /
- public boolean isFull( )
-
- return false
-
- /
- _at_return true if stack is empty,
otherwise return false. - /
- public boolean isEmpty( )
-
- return top null
-
43- public void makeEmpty( )
-
- top null
-
- /
- _at_return top of stack, or null if
empty. - /
- public Object top( )
-
- if( isEmpty( ) )
- return null
- return top.element
-
Top does not change stack.
Can choose to throw exception.
44- /
- remove element on top of stack.
- _at_exception Underflow if stack is
empty. - /
- public void pop( ) throws Underflow
-
- if( isEmpty( ) )
- throw new Underflow( )
- top top.next
-
-
Can choose to do nothing.
Just moving the pointer over.
45- /
- top() and pop()
- _at_return popped item, or null if the
stack is empty. - /
- public Object topAndPop( )
-
- if( isEmpty( ) )
- return null
- Object topItem top.element
- top top.next
- return topItem
-
Can choose to throw exception.
46- /
- put new element on top of stack.
- _at_param x element we want to put in
stack. - /
- public void push( Object x )
-
- top new ListNode( x, top )
-
Old node
New node
New top points to old top.
47Stack weakness
- When popped out, an element disappear forever.
- We need to keep elements in extra variables, or
another stack.
48Creating stack with array
- Do not forget that we need to specify array size.
- Let a stack have
- arrayBody
- topIndex index of the top element. (-1 if the
stack is empty.)
49Code stack made from array
- public class StackFromArray
- private Object arrayBody
- private int topIndex
- static final int DEFAULT_CAPACITY 10
- public StackFromArray( )
-
- this( DEFAULT_CAPACITY )
-
-
50- /
- create a stack, specifying its
capacity. - _at_param capacity number of elements the
- stack can hold.
- /
- public StackFromArray( int capacity )
-
- arrayBody new Object capacity
- topIndex -1
-
51- public boolean isEmpty( )
-
- return topIndex -1
-
- public boolean isFull( )
-
- return topIndex arrayBody.length -
1 -
- public void makeEmpty( )
-
- topIndex -1
-
52- public Object top( )
-
- if( isEmpty( ) )
- return null
- return arrayBody topIndex
-
- /
- remove top element from stack.
- _at_exception Underflow if the stack is
empty. - /
- public void pop( ) throws Underflow
-
- if( isEmpty( ) )
- throw new Underflow( )
- arrayBody topIndex-- null
-
Can choose to throw exception.
Set to null
Then move index
53- /
- Remove top element from stack and return that
element. - _at_return object on top of stack or null if the
stack is empty. - /
- public Object topAndPop( )
-
- if( isEmpty( ) )
- return null
- Object topItem top( )
- arrayBody topIndex- - null
- return topItem
-
Can choose to throw exception.
54- /
- put x in stack if the stack is not full
- _at_param x object to put on top of tack.
- _at_exception Overflow if the stack is
full. - /
- public void push( Object x ) throws
Overflow -
- if( isFull( ) )
- throw new Overflow( )
- arrayBody topIndex x
-
move index and then put x in.
55Using stack (1)
- Balancing check
- Check bracket pair.
- Read program text.
- If see ( , put it in stack.
- If see ), pop top of stack.
- Print error if do not find ( in stack when
reading ). - When finish, if stack is not empty -gt error too.
56Using stack (2)
- Postfix expression (reverse polish)
- 7(89)510 7 8 9 5 10
- We can use stack to evaluate a postfix
expression - Read a number -gt push to stack.
- Read an operator -gt pop numbers in the stack and
use the operator on the numbers.
9
Example reading the first three numbers.
8
7
57When reading
put the result back in stack.
Pop two numbers, multiply.
9
8
72
7
7
Then read 5 in normally.
read , pop the top two and add them.
5
5
72
72
77
7
7
7
58The same for the second .
77
7
84
When reading , pop the top two and them.
Reading 10 normally.
10
10
84
84
840
answer
59Using stack (3)
- Change infix to postfix
- Operand -gt output it right away.
- operator -gt keep it on stack.
- Keep ( on stack too.
- When reading )-gt pop and output continuously
until we find ). - Lets see an example.
60abc(def)g
read a,,b -gt put a and b in output. Put on
top of stack.
a b
read and read c -gt put on top of stack. Put
c in output.
a b c
read -gt must pop equal (or more) priority
operator out to output, before we push the on
top of stack.
a b c
new
61read ( and d -gt put ( into stack, waiting
for ). We put d to output.
(
a b c d
Then, reading and e.
(
a b c d e
pushed in after popping equal (or more)
priority operators.
Next, and f
(
a b c d e f
62Next is ) -gt pop everything up to (.
Pop
(
a b c d e f
Next are and g -gt push into stack. Put g to
output.
a b c d e f g
No more input, we pop everything on stack to
output.
a b c d e f g
63Using stack (4)
- Change infix to prefix
- If reading a number from input
- Put that number in our operand stack.
- If reading an operator
- If operator stack is empty, push it in.
- If the operator is (, push it in the operator
stack. - If the operator has more priority than the
operator on top of the operator stack, push it in
the operator stack.
64- If the operator has equal or less priority than
the operator on top of the stack - Pop an operator from the operator stack.
- Pop operands used by popped operators from the
operand stack. - Put the operator first, followed by the operands.
The latest one is put first. - Put the result in the operand stack.
- If the operator is ), or if we cannot read from
input any further, follow step 4 until the top of
the operand stack becomes (. Then pop that (
out.
65bsqrt(bx dac)/(ea)
First, read ,b. put each one in its stack.
Operand stack
Operator stack
b
-
read . Because has equal priority to (which
is on the operator stack), we need to pop out
and put - with its operand.
-b
66Then read sqrt and (. Sqrt is just like a
method. Therefore it has more priority than other
operations. We push it in stack. We also put (
in stack.
Next are b, , x. we can push all of them.
67Next is . Because is less important than , we
must pop out and work with it.
Then read d, , a. is more important than -,
therefore we can push it in stack. We can also
push d and a.
68Next we read . This time another is on top of
the stack. We then must pop stack and push result
back.
Then read c and push it (no drawing this time).
69Then read ). Pop stack and arrange operators
and operands until we find (. Then remove (.
Then pop out.
Then read / -gt less priority than sqrt.
Therefore we pop sqrt to work.
70Then read ( and e. Push them.
Then read and a. Push them.
71Then read ). Pop to work and remove the
bracket.
Now we finish input reading. We then pop
operators to work with operands. First, pop /.
Then pop . The overall result is on the operand
stack.
-b/ sqrt - bxdacea
72Using stack (5)
- Store method call data
- Local variables of a method must be stored
independently, to prevent name clash with
variables in other methods. - Must store the return point of a method.
- We can create a stack to store a method data.
- activation record or stack frame
73method1() method2() method2() method3()
method3() main () method1()
top
method3s info
method2s info
method1s info
74Careful with method
- There is a form of recursion which wastes stack.
- It is called tail recursion.
- recursive call on the last line of a method.
myAlgo(ListNode p) if (p null) return //d
o something myAlgo(p.next)
For each call, it just call another method
without. Each stack will not contain any data- a
waste.
75fixing tail recursion
- Let compiler handle it or
- Write a loop instead.
myAlgo(ListNode p) while(true) if (p
null) return //do something p
p.next
76Queue
- It is a list.
- But we can put things in at the back only
(enqueue). And we can remove things from the
front only (dequeue). - We can implement queue using
- A modified list
- array
8 4 3 6 7
back
front
77Enqueue and dequeue for queue built from array (1)
- enqueue(x)
- size
- back
- theArrayback x
- dequeue()
- size- -
- front
78Enqueue and dequeue for queue built from array (2)
- Be careful.
- Fix it by making the index go round.
8 4 3 6 7 10
back
front
Cannot Enqueue even though there are spaces at
the front.
9 8 4 3 6 7 10
back
front
79Enqueue and dequeue for queue built from array (3)
- when back front-1, a queue can be either empty
or full. - Therefore we have size.
- Fix error when
- Adding an item to a full queue.
- Dequeue an empty queue.
80- public class QueueArray
- private Object theArray
- private int size
- private int front
- private int back
- static final int DEFAULT_CAPACITY 10
- public QueueArray( )
-
- this( DEFAULT_CAPACITY )
-
- public QueueArray( int capacity )
-
- theArray new Object capacity
- makeEmpty( )
-
81- public boolean isEmpty( )
-
- return size 0
-
- public boolean isFull( )
-
- return size theArray.length
-
- public void makeEmpty( )
-
- size 0
- front 0
- back -1
-
82- public Object getFront( )
- if( isEmpty( ) )
- return null
- return theArray front
-
- /return an item at the front of the
queue, delete that item. Return null if the queue
is empty./ - public Object dequeue( )
- if( isEmpty( ) )
- return null
- size--
- Object frontItem theArray front
- theArray front null
- front increment( front )
- return frontItem
-
Can throw exception.
Can throw exception.
83- /
- put x at the back of queue.
- _at_param x object to be put in the
queue. - _at_exception Overflow if the queue is
full. - /
- public void enqueue( Object x ) throws
Overflow -
- if( isFull( ) )
- throw new Overflow( )
- back increment( back )
- theArray back x
- size
-
-
84- /
- increment array index, allowing the
index to go round the array. - _at_param x array index, must be a legal
index. - _at_return x1, or 0 if x is the at the
back of the array. - /
- private int increment( int x )
-
- if( x theArray.length )
- x 0
- return x
-
85double-ended queue
- insertFirst(Object o) put o at the front.
- insertLast(Object o) put o at the back.
- removeFirst() remove the front element.
- removeLast() remove the last element.
- first() return the first element.
- last() return the last element.
- size() return the queue size.
- isEmpty() test if the queue is empty.
86stack double-ended queue
size() size()
isEmpty() isEmpty()
top() last()
push(x) insertLast(x)
pop() removeLast()
87queue double-ended queue
size() size()
isEmpty() isEmpty()
getFront() first()
enqueue(x) insertLast(x)
dequeue() removeFirst()
88Queue usage
- printer
- Jobs waiting at a printer can jump queue
according to job priority. - Supermarket queue simulation.
- Used queue simulation to decide whether to
increase service size. - Call center queue.
89Supermarket queue
- We can find an average waiting time.
90- If customer come at time -gt 30, 40, 60,110, 170
Waiting time for the 2nd customer.
Waiting time for the 3rd customer.
A11
A2
A3
A4
A5
D2
D3
1st customer paying
2nd customer paying