Anda di halaman 1dari 58

Stack and Queue

Kuliah Algoritma dan Struktur Data


Abstract Data Type (ADT)

ADT : A collection of data and operating methods that represent


abstract properties to the "user" by hiding how they are
represented in lower-level data representations.
Examples : Stack, Queue, Linked List, Tree, dll.

2
Outline
• ADT Stacks
• Operasi dasar
• Contoh kegunaan
• Implementasi
• Array-based dan linked list-based
• ADT Queues
• Operasi dasar
• Contoh kegunaan
• Implementasi
• Array-based dan linked list-based
Tujuan
• Memahami cara kerja dan kegunaan stack & queue
• Dapat mengimplementasi stack dan queue
Struktur Data Linear
• Kumpulan elemen yang tersusun sebagai garis linear
• Stack: struktur data linear di mana penambahan/pengurangan elemen dilakukan di satu ujung
saja.
LIFO (Last In First Out)
• Queue: struktur data linear di mana penambahan komponen dilakukan di satu ujung, sementara
pengurangan dilakukan di ujung lain (yang satu lagi).
• Kedua struktur tersebut merupakan ADT di mana implementasi pada tingkat lebih rendah dapat
sebagai list, baik menggunakan struktur sequential (array) atau struktur berkait (linear linked-list).
Stack
• Semua akses dibatasi pada elemen yang paling akhir disisipkan
• Operasi-operasi dasar: push, pop, top.
• Operasi-operasi dasar memiliki waktu yang konstan
Application

• Stack can be used to check a program for balanced symbols


(such as {}, (), []).
• Example: {()} is legal, {(}) is not (so simply counting symbols
does not work).
• When a closing symbol is seen, it matches the most recently
seen unclosed opening symbol. Therefore, a stack will be
appropriate.
Balanced Symbol Algorithm
• Buat stack baru yang kosong.
• Secara berulang baca token-token; jika token adalah:
• Kurung buka, push token ke dalam stack
• Kurung tutup, maka
• If stack kosong, then laporkan error;
• else pop stack, dan periksa apakah simbol yang di-pop merupakan pasangannya (jika
tidak laporkan error)
• Di akhir file, jika stack tidak kosong, laporkan error.
Contoh
• Input: {()}
• Push ‘{’
• Push ‘(’; lalu stack berisikan ‘{’, ‘(’
• Pop; popped item adalah ‘(’ yang adalah pasangan dari ‘)’. Stack sekarang berisikan ‘{’.
• Pop; popped item adalah ‘{’ yang adalah pasangan dari ‘}’.
• End of file; stack kosong, jadi input benar.
Performance
• Running time adalah O (N), yang mana N adalah jumlah data (jumlah
token).
• Algoritma memproses input secara sikuensial, tidak perlu backtrack
(mundur).
Call Stack
• Kasus balanced symbol serupa dengan method call dan method return, karena saat terjadi suatu
method return, ia kembali ke method aktif yang sebelumnya.
• Hal ini ditangani dengan call stack.
• Ide dasar: ketika suatu method call terjadi, simpan current state dalam stack. Saat return,
kembalikan state dengan melakukan pop stack.
Contoh-contoh di dunia luar komputer

• Tumpukan kertas
• Tumpukan tagihan
• Tumpukan piring
• Waktu O ( 1 ) per operasi stack. (Dengan kata lain, waktu konstan per
operasi, tidak bergantung berapa banyak item yang tersimpan dalam
stack).
Aplikasi Lainnya
• Mengubah fungsi rekursif menjadi non- rekursif dapat dilakukan dengan stack.
• Lihat diskusi di forum rekursif mengenai maze runner, coba buat versi non-rekursif dengan
bantuan stack.
• Operator precedence parsing
• Pembalikan urutan (reversing) dapat dengan mudah dilakukan dengan bantuan stack
Implementasi Array
• Stack dapat diimplementasi dengan suatu array dan suatu integer top yang mencatat indeks
dalam array dari top of the stack.
• Untuk stack kosong maka top berharga -1.
• Saat terjadi push, lakukan dengan increment counter top, dan tulis ke dalam posisi top tsb
dalam array.
• Saat terjadi pop, lakukan dengan decrement counter top.
Ilustrasi
• Apa yang terjadi bila nilai top = ukuran array?
Array Doubling
• Jika stack full (karena semua posisi dalam array sudah terisi), kita dapat memperbesar array,
menggunakan array doubling.
• Kita mengalokasi sebuah array baru dengan ukuran dua kali lipat semula, dan menyalin isi array
yang lama ke yang baru:
Running Time
• Tanpa adanya array doubling, setiap operasi memiliki waktu konstan, dan tidak bergantung pada
jumlah item di dalam stack.
• Dengan adanya array doubling, satu operasi push dapat (namun jarang) menjadi O(N). Namun,
pada dasarnya adalah O(1) karena setiap array doubling yang memerlukan N assignments
didahului oleh N/2 kali push yang non-doubling.
• Teknik Amortization
Stack Implementation (Array)
Implementasi Linked List
• Item pertama dalam list: top of stack (empty = null)
• push(Benda x):
• Create sebuah node baru
• Sisipkan sebagai elemen pertama dalam list
• pop():
• Memajukan top ke item kedua dalam list
Java Built-in Stack
import java.util.Stack;

public class Demo{


public static void main(String[] args){
Stack<Integer> st = new Stack<Integer>();
st.push(10);
// what other methods are available?
}
}
Stack Implementation (Linked List)
Queue
Linear Data Structures

• A collection of elements or items that forms a linear line


• Queue: a linear data structure in which the insertion of
components is done at one end (front), while removal of
components is done at the other end (rear).
FIFO (First In First Out)
• Queue is an abstract data structure where implementation at
lower levels can use a sequential structure (array) or a linked
structure (linked-list).
Queue
• Setiap akses dibatasi ke elemen yang paling terdahulu disisipkan
• Operasi-operasi dasar: enqueue, dequeue, getFront.
• Operasi-operasi dengan waktu konstan. Waktu operasi yang O(1) karena mirip dengan stack.
Contoh
• Antrian Printer
• Antrian Bioskop
Aplikasi-aplikasi
• Queue berguna untuk menyimpan pekerjaan yang tertunda.
• Kita kelak akan melihat beberapa contoh penggunaannya dalam
kuliah-kuliah selanjutnya:
• Shortest paths problem (minimize the number of connecting flights between
two arbitrary airports)
• Topological ordering: given a sequence of events, and pairs (a,b) indicating
that event a MUST occur prior to b, provide a schedule.
Contoh di dunia nyata ?
Implementasi dengan Array-cara naive
• Simpan item-item dalam suatu array dengan item terdepan pada index nol dan item terbelakang
pada index back.
• Enqueue mudah & cepat: increment back.
• Dequeue tidak efisien: setiap elemen harus digeserkan ke depan. Akibatnya: waktu menjadi O(N).
Ide yang lebih baik
• Menggunakan front untuk mencatat index terdepan.
• Dequeue dilakukan dengan increment front.
• Waktu Dequeue tetap O(1).
Queue Penuh
• Apa yang terjadi bila index back = Array.length-1 ?
• Queue penuh?
• Perlukah dilakukan array doubling?
• Apa yang terjadi bila queue kemudian di enqueue, hingga index
first = Array.length-1 ?
• Apakah queue penuh?
• Perlukan dilakukan array doubling?
Implementasi Array Circular
• Solusi: gunakan wraparound untuk menggunakan kembali sel-sel di awal array yang sudah kosong akibat
dequeue. Jadi setelah increment, jika index front atau back keluar dari array maka ia kembali ke 0.
Implementasi dengan Linked List
• Simpan 2 reference: front → ... → ... → back
• enqueue(Benda x):
• Buat sebuah node baru N yang datanya x
• if queue sebelumnya empty, maka front = back = N else tambahkan N di akhir
(dan update back)
• dequeue():
• Hapus elemen pertama: front = front.next
Java Built-in Queue
import java.util.Queue;
import java.util.LinkedList;

public class Demo{


public static void main(String[] args){
Queue<Integer> q = new LinkedList<Integer>();
q.add(100);
// what other methods are available?
}
}
Implementasi Queue dengan Linked List
Poin Penting terkait Queue
• Kedua versi, baik array maupun linked-list berjalan dengan O(1)
• Linked-list memiliki overhead akibat diperlukannya reference next pada setiap node
• Khusus untuk Queue, implementasi array lebih sulit dilakukan (secara circular)
• Memperbesar kapasitas dalam implementasi array (arrayDoubling) memerlukan space
sekurangnya 3x jumlah item data!
Parsing Arithmatics
Expression
Parsing Arithmetic Expression
Parsing (that is, analyzing) arithmetic expressions such as
• 2+3 or
• 2*(3+4)
• ((2+4)*7)+3*(9–5)

The storage structure it uses is the stack.


Algorithm
1. Transform the arithmetic expression into a different format, called
postfix notation.
2. Evaluate the postfix expression.
Infix Notation
• Everyday arithmetic expressions are written with an operator (+, –, *,
or /) placed between two operands (numbers, or symbols that stand
for numbers).
• This is called infix notation because the operator is written inside the
operands.
• Thus, we say 2+2 and 4/7, or, using letters to stand for numbers, A+B
and A⁄B.
Postfix Notation
• In postfix notation, the operator follows the two operands.
• Thus, A+B becomes AB+, and A/B becomes AB/.
Postfix Notation

Infix Postfix
A+B-C AB+C-
A*B/C AB*C/
A+B*C ABC*+
A*B+C AB*C+
A*(B+C) ABC+*
A*B+C*D AB*CD*+
(A+B)*(C-D) AB+CD-*
((A+B)*C)-D AB+C*D-
A+B*(C-D/(E+F)) ABCDEF+/-*+
Practices
Convert the following to postfix:
• 3*5
• 3+8*4 (remember the rules of precedence!)
• (3+4)*(4+6)
Translating Infix to Postfix
Think conceptually first. How do we evaluate something like: 2*(3+4)
to get 14?
• Read left to right
• When we’ve read far enough to evaluate two operands and an
operator - in the above case, 3+4
• Evaluate them: 3+4=7
• Substitute the result: 2*7 = 14
• Repeat as necessary
Parsing in our Heads
2*(3+4)
We have to evaluate anything in parentheses before using it
— Read Parsed
—2 2
— 2* 2*
— 2*( 2*(
— 2*(3 2*(3
— 2*(3+ 2*(3+
— 2*(3+4) 2*(3+4)
— 2*7
14
Parsing in our Heads
2*(3+4)
We have to evaluate anything in parentheses before using it
— Read Parsed
—2 2
— 2* 2*
— 2*( 2*(
— 2*(3 2*(3
— 2*(3+ 2*(3+
— 2*(3+4) 2*(3+4)
— 2*7
14
Precedence

— 3+4*5
— Note here we don’t evaluate the ‘+’ until we know what follows the 4 (a
‘*’)
— So the ‘parsing’ proceeds like this:
— Read Parsed
—3 3
—+ 3+
—4 3+4
—* 3+4*
—5 3+4*5
— 3+20
— 23

47
Summary
• We go forward reading operands and operators
• When we have enough information to apply an operator, go backward
and recall the operands, then evaluate
• Sometimes we have to defer evaluation based on precedence

• Think about this when we do the conversion

48
Infix to Postfix: Algorithm
• Start with your infix expression, and an empty postfix string
• Infix: 2*(3+4) Postfix:
• Go through the infix expression character-by-character
• For each operand:
• Copy it to the postfix string
• For each operator:
• Copy it at the ‘right time’
• When is this? We’ll see

49
Example: 2*(3+4)
• Read Postfix Comment
•2 2 Operand
•* 2 Operator
•( 2 Operator
•3 23 Operand
•+ Operator
•4 234 Operand
•) 234+ Saw ), copy +
• 234+* Copy remaining ops

50
Example: 3+4*5
• Read Postfix Comment
•3 3 Operand
•+ 3 Operator
•4 34 Operand
•* 34 Operator
•5 345 Operand
• 345* Saw 5, copy *
• 345*+ Copy remaining ops

51
Rules on copying operators
• You cannot copy an operator to the postfix string if:
• It is followed by a left parenthesis ‘(‘
• It is followed by an operator with higher precedence (i.e., a ‘+’ followed by a
‘*’)
• If neither of these are true, you can copy an operator once you have
copied both its operands

• We can use a stack to hold the operators before they are copied.
Here’s how:

52
How can we use a stack?
— Suppose we have our infix expression, empty postfix string
and empty stack S. We can have the following rules:
— If we get an operand, copy it to the postfix string
— If we get a ‘(‘, push it onto S
— If we get a ‘)’:
— Keep popping S and copying operators to the postfix string until either S is empty
or the item popped is a ‘(‘
— Any other operator:
— If S is empty, push it onto S
— Otherwise, while S is not empty and the top of S is not a ‘(‘ or an operator of
lower precedence, pop S and copy to the postfix string
— Push operator onto S

— To convince ourselves, let’s try some of the expressions


53
Example: 3+4*5
• Read Postfix Stack

54
Evaluating postfix expressions
• If we go through the trouble of converting to postfix,
there’s got to be a reason, right?
• Well, there is! The resulting expression is much easier to
evaluate, once again using a stack

• Take one example: 345*+


• For every operand push it onto a stack
• Everytime we encounter an operator, apply it to the top two
items and pop them, then push the result on the stack
• We’re done when we have a result and the stack is empty
• Let’s do some examples!

55
Example: 234*+
• Read Stack Comment
•2 2 Operand
•3 23 Operand
•4 234 Operand
•* 2 12 Apply * to 3 and 4
push result
•+ 14 Apply + to 2 and 12
push result

56
Why easier?
• It is clear what operators go with which operands
• Order of operations is enforced – removed from our concern
• No parentheses to worry about

57
THANK YOU

Anda mungkin juga menyukai