inf202: struktur data tumpukan - upj€¦ · –push : simpan,masuk,insert,tulis ... • dengan...
TRANSCRIPT
Pertemuan 9 & 10:
INF202: Struktur Data
TUMPUKAN (STACK)
Dosen: Wayan Suparta, PhD
Pengertian STACK
• Dalam Struktur Stack digunakan istilah :
– PUSH : Simpan,Masuk,Insert,Tulis
– POP : Ambil,Keluar,Delete,Baca
• STACK ada 2 jenis :
– Single Stack
– Double Stack
A
B
C
D TOP
IN OUT
Berlaku prinsip
LIFO (Last In First Out)
A
B
C
D • Dari gambar disamping kita bisa mengatakan bahwa kotak B ada diatas kotak A dan ada dibawah kotak C.
• STACK berarti tumpukan. • Konsep STACK digunakan
dalam struktur data.
Maximum
5
4
3
2
1
0
Stack S
Isi [1]
Isi [2]
Isi [3]
Isi [4]
Isi [5]
• Gambar dibawah ini hanya menunjukkan bahwa dalam tumpukan kita hanya bisa menambah atau mengambil sebuah kotak lewat satu ujung, yaitu ujung bagian atas .
Deklarasi Struktur Data
Stack = Record
Isi : array[1..n] of Tipe Data
Atas : integer
End
Algoritma PUSH
if (Top < n-1)
{
Top = Top+1;
S[Top]=x;
}
else
cout<<“Stack
Penuh”;
Algoritma POP
if (Top > -1)
{
x = S[Top];
Top = Top-1;
}
else
cout<<“Stack
Kosong”;
Kondisi Single Stack
• Kondisi Stack ditentukan oleh posisi atau isi TOP.
Kondisi Stack Posisi TOP
KOSONG Top = -1
PENUH Top = n-1
BISA DIISI Top < n-1
ADA ISINYA Top > -1
9 HARDISK
8 MOUSE
7 SPEAKER
6 MEJA
5 KEYBOARD
4 LAPTOP
3 PRINTER
2 MONITOR
1 VCD
0 TV
Max_Stack
Top=1
Ilustrasi Stack pada kondisi Full IsFull
Fungsi IsFull
• Untuk memeriksa apakah stack sudah penuh?
• Dengan cara memeriksa top of stack, jika sudah sama dengan MAX_STACK-1 maka full, jika belum (masih lebih kecil dari MAX_STACK maka belum full
Fungsi IsEmpty
• Untuk memeriksa apakah data Stack masih kosong?
• Dengan cara memeriksa top of stack, jika masih -1
maka berarti data Stack masih kosong!
Operasi Push adalah menambah elemen ke dalam
stack S, dimana penambahan dapat dilakukan jika
stack itu belum penuh.
Stack dikatakan penuh Jika posisi atas sudah
berada pada posisi N
(if S.atas = n then stack penuh)
Push( x,s) adalah memasukkan x ke dalam Stack
S
Push(x,s)
Procedure Push(x :Tipe data, S : Stack)
If s.atas< n then
s.atas= s.atas+1
s.isi[s.atas] = x
Else
stack sudah penuh
fi
Stack S
Atas = 0
Push(x,s)
Procedure Push(x :Tipe data, S : Stack)
If s.atas< n then
s.isi[s.atas] = x
Else
stack sudah penuh
fi
Stack S
Atas = 1
S.Atas = s.atas + 1
Push(x,s)
Procedure Push(x :Tipe data, S : Stack)
If s.atas< n then
S.atas= s.atas+1
Else
stack sudah penuh
fi
Stack S
Atas = 1 S.isi[S.atas] = k
Push(x,s)
Procedure Push(x :Tipe data, S : Stack)
If s.atas< n then
s.isi[s.atas] = x
Else
stack sudah penuh
fi
Stack S
Atas = 2 S.Atas = s.atas + 1
Push(x,s)
Procedure Push(x :Tipe data, S : Stack)
If s.atas< n then
S.atas= s.atas+1
Else
stack sudah penuh
fi
Stack S
Atas = 2
S.isi[S.atas] = k
Push(x,s)
Procedure Push(x :Tipe data, S : Stack)
If s.atas< n then
s.isi[s.atas] = x
Else
stack sudah penuh
fi
Stack S
Atas = 3
S.Atas = s.atas + 1
Push(x,s)
Procedure Push(x :Tipe data, S : Stack)
If s.atas< n then
S.atas= s.atas+1
Else
stack sudah penuh
fi
Stack S
Atas = 3
S.isi[S.atas] = k
Push(x,s)
Procedure Push(x :Tipe data, S : Stack)
If s.atas< n then
S.atas= s.atas+1
S.isi[S.atas] = k
Else
fi Stack S
Atas = 5
stack sudah penuh
Double Stack
• Disebut juga Stack Ganda.
6 23
10 11
2
TOP 1 X
8
TOP 2
S[12]
TOP 1 TOP 2
25 12
0 1
17
2 3 4 5 6
50
7 8
44
9
Stack 1 Stack 2
-1 12
Prinsip dan Konsep Proses Double
Stack
• Prinsip proses : LIFO (Last In First Out) baik untuk Stack1 maupun
untuk Stack2
• Proses pada Double Stack :
• AWAL (Inisialisasi)
• PUSH1 (Push untuk Stack1)
• POP1 (Pop untuk Stack1)
• PUSH2 (Push untuk Stack2)
• POP2 (Pop untuk Stack2)
Kondisi Double Stack
Kondisi Stack Posisi TOP
Stack1 KOSONG Top1 = -1
Stack2 KOSONG Top2 = n
Stack PENUH (baik Stack1 maupun
Stack2 tidak BISA DIISI)
Top2 – Top1 = 1
Stack BISA DIISI (baik Stack1
maupun Stack2 BISA DIISI)
Top2 – Top1 > 1
Stack1 ADA ISINYA Top1 > -1
Stack2 ADA ISINYA Top2 < n
Algoritma PUSH1
(mengisi Stack1)
• Periksa apakah Stack1 BISA DIISI
if (Top2 – Top1 > 1)
{ Top1 = Top1 + 1;
S[Top1] = x;
}
else
cout<<“Stack Penuh”;
Algoritma POP1
(mengambil isi Stack1)
• Periksa apakah Stack1 ADA ISINYA
if (Top1 > -1)
{ x = S[Top1];
Top1 = Top1 - 1;
}
else
cout<<“Stack Kosong”;
Algoritma PUSH2
(mengisi Stack2)
• Periksa apakah Stack2 BISA DIISI
if (Top2 – Top1 > 1) {
Top2 = Top2 - 1;
S[Top2] = x;
}
else
cout<<“Stack Penuh”;
Algoritma POP2
(mengambil isi Stack2)
• Periksa apakah Stack2
ADA ISINYA
if (Top2 < n)
{
x = S[Top2];
Top2 = Top2 + 1;
}
else
cout<<“Stack
Kosong”;
Mencek kalimat Polindrom Kalimat : KAKAK
K
A
K K
A
K
K
A
K
A
K
A
K
A
K
Operasi Push
1. Untuk mencek kalimat Polindrom
2. Untuk Mengubah Desimal ke Biner
Operasi Pop
K
A
K
K
A
K
A
K
A
K
A
K K
A
K
Hasil =‘’
Hasil = K
Hasil = KA Hasil = KAK Hasil = KAKA Hasil = KAKAK
Kalimat = hasil
Polindrom
Contoh 1: Program Single stack #include <cstdlib> #include <string> #include <iostream> using namespace std; //stack 7 int top=-1; char stack[2];//asumsi max stack 100 char x; void push() //menyimpan { cout<<"masukkan satu karakter: "; cin>>x; top++; stack[top]=x; } { if(top<0) { cout<<"stack kosong"<<endl; return; } x=stack[top]; top--; cout<<"karakter yang di 'POP' adalah
"<<x<<endl; }
void cetak() //mencetak
{
if(top<0)
{
cout<<"stack kosong" <<endl;
return ;
}
int i=0;
for(i=top;i>=0;i--)
cout<<stack[i]<<endl;
}
int main(int argc, char *argv[])
{
int input;
cout<<"MASUKKAN PILIHAN: "<<endl;
cout<<"\t1. PUSG"<<endl;
cout<<"\t2. POP"<<endl;
cout<<"\t3. PRINT"<<endl;
cout<<"\t4. QUIT"<<endl;
while(true)
Contoh: Program Single stack {
cout<<"\nMasukan pilihan: ";
cin>>input;
if(input==1) {push();}
else if(input==2) {pop();}
else if(input==3) {cetak();}
else if(input==4) {break;}
else
{
cout<<"Perintah ' "<<input<<" tidak dikenal"<<endl;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
Output:
Contoh 2: Konversi 17910 ke biner: 179 / 2 = 89 sisa 1 (LSB) / 2 = 44 sisa 1 / 2 = 22 sisa 0 / 2 = 11 sisa 0 / 2 = 5 sisa 1 / 2 = 2 sisa 1 / 2 = 1 sisa 0 / 2 = 0 sisa 1 (MSB) 17910 = 101100112
MSB LSB
Konversi Bilangan Desimal ke Biner
Contoh 2: Konversi Desimal ke Biner #include<iostream> #include<stdio.h> #include<conio.h> int MAXSTACK; typedef int itemtype; typedef struct { itemtype item[300]; int count; } stack; void initializestack(stack *s) { s->count = 0; } int empty(stack *s) { return (s->count == 0); } int full(stack *s) { return (s->count ==
MAXSTACK); }
void push(itemtype x, stack *s) { if(full(s)) printf("stack penuh !\n"); else { s->item[s->count]=x; ++(s-
>count); } } int pop(stack *s) { if(empty(s)) printf(" Stack Kosong "); else { --(s->count); return (s->item[s->count]); } }
using namespace std;
main()
{
int i, n, m, l, z; int input;
stack tumpukan;
printf(" Program Pengkonversi Desimal ke Biner ");
cout<<endl<<endl;
initializestack(&tumpukan);
printf(" Masukkan Bilangan Desimal : ");
scanf("%d", &input);
for(z=1,n=input;n>0;n=n/2, z++)
{
MAXSTACK=z;
}
m=0; for(n=input;n>0;n=n/2) { l=n%2; push(l,&tumpukan); ++m; } cout<<endl; printf(" Hasil Konversi Ke
Bilangan Biner : "); for(i=MAXSTACK;i>0;i--) { printf("%d",
pop(&tumpukan)); } getch(); return 0; }
Penerapan Stack: Ungkapan Aritmatika
Untuk menuliskan ungkapan aritmatika dapat
dilakukan dengan tiga metode
Infix Operan Operator Operan: A + B
Prefix Operator Operan Operan: +A B
Postfix Operan Operan Operator: A B+
Derajat Operator
(, ^ , * dan /,+ dan -
Contoh lain:
Contoh :
1. Infix : A + B + C
Prefix +AB + C
++ABC
Postfix AB+ + C
AB+C+
2. Infix A+B * C
Prefix: A+*BC
+A*BC
Postfix: A+ BC*
ABC*+
3. Infix: A*B + C*D
Prefix: *AB + C * D
*AB + *CD
+*AB*CD
Postfix: AB* + C*D
AB* + CD*
AB*CD*+
Contoh lain:
Logika Penyelesaiannya:
1. Prefix adalah notasi yang terbentuk atas operator dengan operand, dimana oprator
didepan operand. contoh: A + B * C (infix), maka notasi prefixnya
adalah: +A*BC.
Pemecahannya: A+B*C
Diketahui ada 3 operand yaitu: A, B, C dan 2 operand yaitu: +, *.
Proses dimulai dengan melihat dari hirarkhi oprator. Contoh di atas operator
yang tertinggi adalah * kemudian +. Tanda * diapit oleh 2 operand yaitu B*C.
Prefixnya dengan menggabungkan operand dan memindahkan operator ke depan
dari operand, sehingga fungsi B*C, notasi prefixnya menjadi *BC.
Sehingga hasil sementara dari notasi prefix adalah: A+*BC
Selanjutnya mencari prefix untuk operator yang berikutnya yaitu +.
Cara yang dilakukan sama seperti di atas, operator + diapit oleh operand, yaitu A
dan *BC, gabungkan operand, sehingga menjadi A*BC
Lalu pindahkan operator ke depan operand, sehingga hasil akhir menjadi :
+A*BC.
Stack Untuk Konversi Infix ke postfix
Algoritma
Langkah 0 : inisialisasi struktur data dengan membuat sebuah stack kosong, baca ungkapan dalam bentuk infix, dan tentukan derajat operator misalnya
( : 0 ; + & - : 1;* & / : 2;^ : 3
Langkah 1 : Lakukan pembacaan karakter dari Infix, berikan ke R
Langkah 2 : Test Nilai R, Jika
a. ( Langsung di Push
b. Operand, Langsung di Tulis
c. ) lakukan Pop sampai ketemu buka kurung, tetapi tanda kurung tidak perlu di tulis.
d. Operator, Jika stack dalam keadaan kosong atau derajat R lebih tinggi dibandingkan dengan di ujung stack, lakukan Push, jika tidak lakukan POP.
Langkah 3 : Jika pembacaan terhadap infix sudah selesai, namun stack belum kosong lakukan POP.
Contoh Program INFIX ke PREFIX
// CPP program konversi noatsi infix
ke prefix
#include<stdio.h>
#include<iostream>
#include<conio.h>
#include<string.h>
#include <bits/stdc++.h>
using namespace std;
bool isOperator(char c)
{
return (!isalpha(c) && !isdigit(c));
}
int getPriority(char C)
{
if (C == '-' || C == '+')
return 1;
else if (C == '*' || C == '/')
return 2;
else if (C == '^')
return 3;
return 0;
}
string infixToPostfix(string infix)
{
infix = '(' + infix + ')';
int l = infix.size();
stack<char> char_stack;
string output;
for (int i = 0; i < l; i++) {
// Jika karakter yang dibaca itu dalah sebuah operan,
//tambahkan ke dalam output
if (isalpha(infix[i]) || isdigit(infix[i]))
output += infix[i];
// Jika karakter yang dibaca itu dalah sebuah operan,
// ‘(‘, simpan/masukkan ke dalam stack.
else if (infix[i] == '(')
char_stack.push('(');
// Jika karakter yang dibaca itu dalah sebuah operan,
// ‘)’, pop dan keluarkan dari stack
// sampai ‘(‘ ditemui.
else if (infix[i] == ')') {
INFIX ke PreFIX ….lanjut while (char_stack.top() != '(') {
output += char_stack.top();
char_stack.pop();
}
// Remove '(' dari stack
char_stack.pop();
}
// Operator ditemukan
else {
if (isOperator(char_stack.top())) {
while (getPriority(infix[i])
<= getPriority(char_stack.top()))
{
output += char_stack.top();
char_stack.pop();
}
// Push Operator saat ini dalam
stack
char_stack.push(infix[i]);
}
}
}
return output;
}
string infixToPrefix(string infix)
{
/* Balikkan String
* Ganti ( dengan ) dnd sebaliknya
* Dapatkan Postfix
* Balik Postfix * */
int l = infix.size();
// Balik infix
reverse(infix.begin(), infix.end());
// Ganti ( dengan ) dnd sebaliknya
for (int i = 0; i < l; i++) {
if (infix[i] == '(') {
infix[i] = ')';
i++;
}
else if (infix[i] == ')') {
infix[i] = '(';
i++;
}
}
string prefix = infixToPostfix(infix);
// Balikkan postfix
reverse(prefix.begin(), prefix.end());
return prefix;
}
// Hasilkan notasi
int main()
{
string s = ("(A-B/C)*(A/D-l)");
cout << infixToPrefix(s) << std::endl;
return 0;
}
Contoh Program INFIX ke POSTFIX
#include <iostream>
#include <sstream>
#include <stack>
#include <limits>
#include <string>
using namespace std;
int priority(char a) {
int temp;
if (a == '^')
temp = 1;
else if (a == '*' || a == '/')
temp = 2;
else if (a == '+' || a == '-')
temp = 3;
return temp;
}
int main() {
string infix;
cout << "Masukan Infix : ";
getline(cin, infix);
stack<char> opr_stack;
stringstream postfix;
for (unsigned i = 0; i < infix.length(); i++) {
if (infix[i] == '+' || infix[i] == '-' || infix[i] == '*' || infix[i] == '/' ||
infix[i] == '^') {
while (!opr_stack.empty() && priority(opr_stack.top()) <=
priority(infix[i])) {
postfix << opr_stack.top();
opr_stack.pop(); }
opr_stack.push(infix[i]);
} else if (infix[i] == '(') {
opr_stack.push(infix[i]);
} else if (infix[i] == ')') {
while (opr_stack.top() != '(') {
postfix << opr_stack.top();
opr_stack.pop();
}
opr_stack.pop(); }
else {
postfix << infix[i]; }
}
while (!opr_stack.empty()) {
postfix << opr_stack.top();
opr_stack.pop(); }
cout << "Postfix : " << postfix.str() << endl;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
}
LATIHAN 15 A. Gambarkan kondisi STACK berukuran 10 lokasi berdasarkan
urutan-urutan operasi berikut:
1. PUSH 3 8. PUSH 12 15. PUSH 6
2. PUSH 5 9. PUSH 20
3. PUSH 4 10. PUSH 9
4. PUSH 12 11. PUSH 8
5. PUSH 3 12. PUSH 6
6. PUSH 4 13. PUSH 5
7. PUSH 9 14. PUSH 20
B. Buat program untuk menyiapkan array satu dimensi yang
akan digunakan untuk mengisi Stack S sebanyak 5 elemen,
bertipe integer.
C. Buat algoritma dan program untuk mengkonversi Bilangan desimal menjadi bilangan octal.
D. Buat algoritma dan program untuk mengkonversi Bilangan desimal menjadi bilangan hexa.
E. Buat program untuk (1) menyimpan, (2) menghapus dan (3) cetak elemen dalam stack berupa angka-angka.
F. Diketahui: Infix : A + B * (C – D) / E. Ubahlah ke notasi Prefix dan Posfix
G. Ubahlah notasi aritmatika PREFIX berikut ke notasi POSTFIX: + * A / B + C – D E F
H. Buatlah program bermenu yang dapat mengkonversikan Prefix menjadi Postfix menggunakan Stack.
I. Buatlah program bermenu yang dapat mengkonversikan POSTFIX menjadi INFIX menggunakan Stack.