Anda di halaman 1dari 15

PRAKTIKUM IX

STUKTUR DATA STACK

9.1. Pendahuluan
Stack merupakan list linear yang penghapusan (pop) dan penambahan (push)
elemen hanya dilakukan pada satu sisi yang disebut Top of Stack. Karena penambahan dan
penghapusan hanya pada satu sisi maka dikatakan stack mempunyai sifat LIFO (Last In
First Out) yaitu elemen yang paling akhir ditambahkan adalah elemen yang paling dulu
dihapus dari stack. Ilustrasi stack dapat dilihat pada gambar 9.1 di bawah ini.

Top of Stack

Bottom of Stack
Gambar 9.1 Struktur data Stack

9.2. Operasi Stack


Operasi yang difefinisikan untuk struktur data stack adalah:
1. Inisialisasi: membuat stack kosong, Top of Stack (TOS) = 0
2. Push(S,x): insert elemen x ke stack S
3. Pop(S): delete elemen yang berada pada TOS
4. isEmpty(): apakah stack kosong?
5. TopVal(S): lihat elemen yang ada di TOS

9.3. Implementasi Stack


Sama seperti struktur data List yang telah dibahas, struktur data stack dapat
diimplementasikan dengan struktur data array dan linked list. Implementasi stack dengan
array menyebabkan ukuran stack menjadi terbatas, yaitu sesuai dengan definisi ukuran
array sehingga perlu dibuat suatu statement tambahan yang memeriksa apakah ukuran stack
sudah mencapai maksimum atau belum. Jika sudah mencapai maksimum (stack overflow)
maka operasi Push(S,x) tidak dapat dilakukan. Sebaliknya implementasi stack dengan
linked list, menjamin ukuran stack yang dinamik dan tidak terbatas. Stack dapat membesar
sesuai kebutuhan, dalam hal ini tidak terjadi stack overflow.

75
Praktikum C++ Lanjut

9.4. Operasi Stack dengan Array


Untuk stack yang diimplementasikan dengan array, stack akan membesar sesuai
dengan pertambahan indeks array. Dengan demikian, untuk stack yang sudah berisi n
elemen maka top of stack berada pada indeks n-1. Maksimum banyaknya elemen yang
dapat disimpan dalam stack adalah sama dengan ukuran array ketika dideklarasikan.
Dengan memperhatikan keterbatasan array, maka fungsi-fungsi untuk operasi stack adalah:
1. Inisialisasi:
void Inisialisasi()
{
Tos=0;
}

Fungsi ini hanya memberi nilai awal pada variabel Tos. Deklarasi array yang
digunakan sebagai stack dan variabel Tos dilakukan pada program utama sehingga
keduanya merupakan global variabel yang dapat diakses oleh semua fungsi.
Contoh deklarasi:
int Tos;
char S[100]; //stack menyimpan maksimum 100 elemen

2. Stack kosong?:
int isEmpty()
{
if (Tos == 0)
return (1);
else
return (0);
}

Jika isi variabel Tos = 0, berarti stack kosong, selain itu stack tidak kosong. Fungsi ini
dapat dibuat fungsi yang berjenis boolean yang menghasilkan true atau false.
3. Push elemen ke stack:
void PUSH(char *S,char X)
{
if (Tos>=N)
cout<<endl<<"Error, Stack is Full!!!" << endl;
else
{
Tos = Tos+1; // increment Tos
S[Tos]=X;
}
}

Karena panjang array yang terbatas, maka stack yang diimplementasikan array menjadi
terbatas juga. Jika varibel Tos sudah mencapai akhir array, maka operasi Push tidak
dapat dilakukan lagi. Untuk mengatasi agar tidak terjadi stack overflow, beberapa buku
referensi melakukan perubahan panjang array sehingga menjadi lebih besar 2 kali

Modul 9 : Struktur Data Stack - 76


Praktikum C++ Lanjut

ukuran semula. Tetapi tidak semua bahasa pemrograman mempunyai fasilitas untuk
melakukan perubahan panjang array di tengah program.
4. Pop elemen dari stack:
char POP(char *S)
{ char Temp;
if (Tos == 0)
{ cout<<endl<<"Error, Stack is Empty "<< endl;
Temp = '#';
return (Temp);
}
else
{ Temp = S[Tos];
Tos = Tos-1; // decrement Tos
return(Temp);
}
}

Seperti telah dijelaskan di atas, elemen yang dihapus dari stack adalah elemen yang
paling atas atau yang berada pada Top of Stack. Setelah elemen dihapus, variabel Tos
di-decrement. Untuk menunjukkan bahwa stack kosong, maka digunakan simbol ’#’
sebagai output dari fungsi ini.
5. Melihat elemen stack yang paling atas
char TOP(char *S)
{
if (Tos == 0)
{ cout<<endl<<"Stack kosong"<< endl;
return ('#');
}
return (S[Tos]);
}

Fungsi ini hanya melihat elemen yang berada pada Top of Stack. Sama seperti fungsi
POP di atas, jika stack kosong maka akan dihasilkan karakter’#’.

Contoh operasi stack:


PUSH(S,’a’);
PUSH(S,’b’);
Cout<<”Isi stack = “<<S<<endl;
PUSH(S,’c’);
PUSH(S,’d’);
PUSH(S,’e’);
Cout<<”Isi stack = “<<S<<endl;
X = POP(S);
Cout<<”Isi stack = “<<S<<” X = “<<X<<endl;
PUSH(S,’f’);
PUSH(S,’g’);
Cout<<”Isi stack = “<<S<<endl;
X = POP(S);
Y = POP(S);
Z = POP(S);
Cout<<”Isi stack = “<<S<<” X = “<<X<<” Y = “<<Y<<” Z = “<<Z<<endl;

Modul 9 : Struktur Data Stack - 77


Praktikum C++ Lanjut

9.5. Aplikasi Stack

Struktur data Stack dapat digunakan untuk memeriksa pasangan tanda kurung,
mengkonveri ekspresi infix menjadi suffix serta mengevaluasi ekspresi suffix

9.5.1. Memeriksa pasangan tanda kurung


Dalam suatu ekspresi aritmematika sering ditemui ekspresi yang ditulis diantara
sepasang tanda kurung, kurung buka dan kurung tutup. Ada 3 pasang tanda kurung yang
biasa digunakan yaitu:
1. ( dan )
2. { dan }
3. [ dan ]

Untuk memeriksa apakah penulisan tanda kurung sudah sesuai (berpasangan)


dapat digunakan struktur data Stack. Algoritma umum untuk memeriksa pasangan tanda
kurung:
1. Buat Stack kosong
2. Baca simbol sampai akhir string:
a. Jika simbol berupa kurung buka, push simbol ke stack
b. Jika simbol berupa kurung tutup:
i. Periksa simbol pada Top of Stack:
A. jika simbol berupa pasangan dari kurung tutup, Pop Stack dan
lanjutkan pembacaan
B. jika simbol bukan berupa pasangannya, tampilkan error message
C. jika stack kosong, tampilkan error message
3. Jika stack tidak kosong maka tampilkan error message.

Untuk masalah ini, dapat digunakan array yang bertipe char sehingga tiap elemen stack
hanya berupa sebuah karakter. Untuk memudahkan dalam pemrograman, hanya ada 3
pasang tanda kurung yang digunakan dan program hanya memeriksa pasangan tanda
kurung saja. Fungsi untuk masalah ini dapat dilihat pada gambar 9.2 di bawah ini.

void pasangan()
{
char eksp[N]; // string untuk menyimpan ekspresi
char s, t;
int i,p;

Modul 9 : Struktur Data Stack - 78


Praktikum C++ Lanjut

cout<<"Masukkan ekpresi = ";cin>>eksp;


cout<<endl;
Inisialisasi(); //inisialisasi stack
p = strlen(eksp);
cout<<"panjang ekspresi "<<p<<endl;
for(i=0; i<=p; ++i)
{
s = eksp[i];
if (s == '{' || s == '[' || s == '(')
PUSH (S, s);
else if (s == '}' || s == ']' || s == ')')
{
t = POP(S);
switch (t)
{ case '{': t = '}'; break;
case '[': t = ']'; break;
case '(': t = ')'; break;
}
if (eksp[i] != t)
{ cout<<" Salah pasangan"<< endl;
return;
}
}
}

if (isEmpty() == 1)
cout<<"Pasangan tanda kurung sesuai"<<endl;
else
cout<<"Tanda kurung tidak berpasangan"<<endl;
system(“pause”);
}
Gambar 8.2 Fungsi untuk memeriksa pasangan tanda kurung

8.5.2. Membuat ekspresi infix menjadi postfix


Ekspresi aritmetika yang biasa dikenal, ditulis dengan cara infix yaitu operator
berada di antara 2 operan atau L O R yang berarti, Left operand, Operator dan Right
operand. Ekspresi infix akan dikerjakan mulai dari kiri ke kanan. Yang menjadi masalah
adalah jika ada bagian ekspresi yang harus dikerjakan lebih dulu tetapi berada di sebelah
kanan. Dalam hal ini bagian ekspresi tersebut perlu ditulis di antara sepasang tanda kurung.
Jika ada beberapa ekspresi yang berada di antara tanda kurung, maka yang dikerjakan
adalah ekspresi yang berada pada tanda kurung yang paling dalam. Sebagai contoh, lihat
ekspresi berikut ini:
X = (-b + (b^2 – (4 * a) * c) ^ (½))/(2 * a)

Seperti telah dijelaskan sebelumnya, penggunaan banyak tanda kurung dapat


menjadi sumber kesalahan dalam penulisan ekspresi. Untuk mengatasi masalah ini, seorang
matematikawan dari Polandia, Jan Lukaseiwicz, menemukan metoda penulisan ekspresi
yang disebut sebagai Reverse Polish Notation atau postfix yang tidak menggunakan tanda

Modul 9 : Struktur Data Stack - 79


Praktikum C++ Lanjut

kurung. Caranya dengan menuliskan operator setelah kedua operan, atau L R O yaitu Left
operand, Right operand, Operator. Sebagai contoh penulisan postfix dan padanan infix-nya
dapat dilihat pada tabel 9.1 di bawah ini.

Tabel 9.1 Ekspresi Infix dan Postfix


Infix Postfix
A+B AB+
A*B+C AB*C+
A * (B + C) ABC+*
(A + B) / (C* (D – E)) AB+CDE-*/
(A ^ 2 + B^ 2) * (C – D) A2^B2^+CD-*

Untuk mengubah ekspresi infix menjadi postfix, digunakan struktur data stack
sebagai tempat penyimpan sementara. Algoritma umum untuk mengubah Infix menjadi
Postfix:
1. Buat stack kosong
2. Baca simbol sampai akhir ekspresi.
3. Jika simbol berupa:
a. Operan: langsung tuliskan sebagai output
b. Kurung buka: push ke stack
c. Kurung tutup: pop stack sampai ketemu kurung buka (tanda kurung tidak ditulis
sebagai outpush)
d. Operator yang derajatnya lebih rendah dari TOP of Stack: pop stack sampai ketemu
operator yang derajatnya lebih rendah, lalu push ke stack:
e. Operator yang derajatnya lebih tinggi dari Top of Stack: push ke stack
f. Akhir simbol: pop stack sampai stack kosong.

Yang perlu diperhatikan dalam menterjemahkan algoritma di atas menjadi program adalah
pada langkah 3.d. Program komputer tidak dapat mengenal operator dan derajatnya.
Dengan demikian perlu dibuat 1 fungsi untuk membandingkan operator yang ada pada Top
of Stack dengan operator yang dibaca. Contoh fungsi dapat dilihat pada gambar 9.3 di
bawah ini.

int cek(char a, char b)


{
switch (a)

Modul 9 : Struktur Data Stack - 80


Praktikum C++ Lanjut

{
case '+': { if (b == '+' || b =='-' || b == '*')
return(1);
else
return(0); // isi top of stack = '(' atau empty
break;}
case '-':{ if (b == '+' || b =='-' ||b == '*')
return(1);
else
return(0);
break;}
case '*':{ if (b == '*')
return(1);
else
return(0); //isi Tos = '(' , '+' , '-' , atau
empty
break}
}

Gambar 9.3 Fungsi untuk memeriksa operator

Fungsi pada gambar di atas, membandingkan operator yang dibaca (argumen a)


dengan operator yang berada pada Top of Stack (argumen b). Jika derajat operator pada
yang dibaca sama atau lebih rendah dari Top of Stack maka akan dihasilkan angka 1, selain
itu angka 0. Fungsi di atas hanya digunakan untuk operator tambah, kurang dan kali (+, -
dan *). Untuk operator lain dapat ditambahkan pada fungsi di atas.
Untuk memudahkan pemrograman, fungsi yang dibuat, hanya dapat digunakan
untuk operator biner, operator yang dikenali hanya +, -, dan *, serta tanda kurung yang
digunakan hanya tanda kurung biasa ( “(“ dan “)”). Stack digunakan untuk menyimpan
operator selama proses konversi. Hasil proses disimpan dalam array postfix[n]. Dengan
demikian fungsi yang lengkap untuk mengubah persamaan infix menjadi postfix dapat
dilihat pada gambar 9.4 berikut.

void infix()
{
char postfix[N],eksp[N];
char x,y, Temp;
int i,j,p,t;
t = 0;
cout<<"Masukkan ekpresi Matematika = ";
cin>>eksp;
cout<<endl;
Inisialisasi(); // inisialisasi stack
p = strlen(eksp);
for(i=0 ; i<= p ; i++)
{
x = eksp[i]; // baca ekspresi per karakter
if (x == '(')
PUSH(S,x);
else if (x =='+' || x =='-'|| x=='*')
{ // jika x adalah operator

Modul 9 : Struktur Data Stack - 81


Praktikum C++ Lanjut

y = TOP(S);
if (y == '#') // jika stack kosong
PUSH(S,x);
else
{ j = cek(x,y); // bandingkan x dengan
while (j == 1) // operator pada Tos
{ //jika derajat < atau
sama
postfix[t]=POP(S); //pop stack
&
t++; //simpan ke array output
y = TOP(S);
j = cek(x,y);
}
PUSH(S,x);
}
}
else if(x == ')') // jika x = ‘)’
{
Temp = POP(S); // pop stack & simpan
while(Temp != '(') // ke array output
{ // sampai ketemu ‘)’
postfix[t]=Temp;
t++;
Temp = POP(S);
}
}
else
{ postfix[t]= x ; // eksp[i] == operan
t++; // simpan ke output
}
}
t--;
cout<<"Selesai ekspresi"<< endl;
p = isEmpty();
while (p != 1)
{
postfix[t]= POP(S);
t++;
p = isEmpty();
}
postfix[t]='\0';
cout<<" Persamaan postfix = "<<postfix<<endl;
getch();
}
Gambar 9.4 Fungsi mengubah infix menjadi postfix

9.5.3. Mengevaluasi persamaan postfix


Untuk mengevaluasi sebuah ekspresi postfix, diperlukan struktur data stack juga.
Algoritma umum untuk mengevaluasi postfix adalah:
1. Buat stack kosong
2. Baca simbol sampai akhir ekspresi
3. Jika ekspresi berupa:
a. Operan, maka push ke stack

Modul 9 : Struktur Data Stack - 82


Praktikum C++ Lanjut

b. Operator, maka
i. R = pop(stack); L = pop(stack)
ii. lakukan operasi, push hasilnya ke stack
4. Hasil ekspresi = pop Stack.
5. Jika stack tidak kosong, tampilkan error message.

Yang perlu diperhatikan pada algoritma di atas adalah pada langkah 3.b, melakukan
operasi untuk 2 operan dan menyimpannya lagi ke stack. Dengan memperhatikan program
yang telah dibuat, array dan stack yang digunakan bertipe char, sehingga hanya dapat
menyimpan sebuah karakter. Dengan demikian, untuk memudahkan pemrograman, maka
nilai maupun hasil evaluasi, hanya berupa 1 digit angka, yaitu angka 0 sampai 9. Untuk
digit yang lebih banyak perlu digunakan array of string dan memerlukan fungsi khusus
untuk mengubah string menjadi angka atau sebaliknya.
Untuk melakukan operasi aritmetika terhadap 2 operan, perlu dikonversi dulu angka
yang bertipe char menjadi angka yang bertipe integer. Konversi ini dilakukan oleh built in
function atoi(char). Setelah dilakukan operasi aritmetika, hasilnya dikonversi kembali
menjadi angka yang bertipe char dengan menggunakan built in function itoa(int,char,base)
sehingga dapat disimpan kembali dalam stack. Fungsi yang dibuat hanya dapat digunakan
untuk operator tambah, kurang dan kali (+, - dan *). Untuk operator lain dapat ditambahkan
pada fungsi Opr(o,a,b) di bawah ini.

char opr(char o, char a, char b)


{ //o adalah operator, a operan kiri, b operan kanan
int x, y,z;
char *c,*d,*e;
d = &a;
e = &b
x = atoi(d); // mengkonversi karakter menjadi integer
y = atoi(e);
switch (o)
{
case '+':{ z = x + y;
itoa(z,c,10); //mengkonversi integer menjadi
break; //karakter
}
case '-':{ z = x - y;
itoa(z,c,10);
break;
}
case '*':{ z = x * y;
itoa(z,c,10);
break;
}
}
d = *c;

Modul 9 : Struktur Data Stack - 83


Praktikum C++ Lanjut

return(d);
}

Gambar 9.5 Fungsi untuk melakukan operasi aritmetika

Fungsi selengkapnya untuk mengevaluasi sebuah persamaan postfix dapat dilihat pada
program 9.6 di bawah ini.

void eval()
{
char eksp[N];
char ki, ka, x, y, Temp;
int i,j, p,t;
t = 0;
cout<<"Masukkan ekpresi postfix = ";
cin>>eksp;
cout<<endl;
Inisialisasi();
p = strlen(eksp);
for(i=0 ; i<= p ; i++)
{
x = eksp[i];
if (isdigit(x)) // jika berupa angka, masukkan ke stack
PUSH(S,x);
else if (x =='+' || x =='-'|| x=='*')
{ // jika berupa operator maka
ka = POP(S); // pop stack 2 kali dan lalukan
ki = POP(S); // operasi aritmetika
y = opr(x,ki,ka);
PUSH(S,y); // simpan hasilnya ke stack
}
}
cout<<"Selesai ekspresi"<< endl;
Temp = POP(S);
if (isEmpty() == 1)
cout<<"Hasil evaluasi = "<<Temp<<endl;
else
cout<<"Persamaan postfix salah"<<endl;

Gambar 9.6 Fungsi untuk mengevaluasi persamaan postfix

Latihan Soal Praktikum 9

1. Buatlah main program dan buatlah menu untuk memanggil fungsi untuk memeriksa
pasangan tanda kurung, mengubah infix menjadi postfix dan mengevaluasi postfix.
2. Lengkapi fungsi cek, fungsi infix, fungsi opr dan fungsi eval sehingga dapat
mengenali operator bagi dan pangkat.
3. Lengkapi fungsi cek, fungsi infix, fungsi opr dan fungsi eval sehingga dapat
mengenali operator unary.

Modul 9 : Struktur Data Stack - 84


Praktikum C++ Lanjut

4. Dalam program terpisah, ubahlah fungsi opr dan fungsi eval sehingga dapat
mengkonversi ekspresi postfix menjadi infix.

#include<iostream>
#include<string.h>

using namespace std;

#define N 100
#define true 1
#define false 0

int Tos;
char S[N];

void Inisialisasi()
{
Tos=0;
}

int isEmpty()
{
if (Tos == 0)
return (1);
else
return (0);
}

void PUSH(char *S,char X)


{
if (Tos>=N)
cout<<endl<<"Error, Stack is Full!!!" << endl;
else
{
Tos = Tos+1;
S[Tos]=X;
}
}

char POP(char *S)


{ char Temp;
if (Tos == 0)
{ cout<<endl<<"Error, Stack is Empty "<< endl;
Temp = ' ';
return (Temp);
}
else
{ Temp = S[Tos];
Tos = Tos-1;
return(Temp);
}
}

char TOP(char *S)


{
if (Tos == 0)
{ cout<<endl<<"Stack kosong"<< endl;

Modul 9 : Struktur Data Stack - 85


Praktikum C++ Lanjut

return ('#');
}
return (S[Tos]);
}

void pasangan()
{
char eksp[N];
char s, t;
int i,p;

cout<<"Masukkan ekpresi = ";cin>>eksp;


cout<<endl;
Inisialisasi();
p = strlen(eksp);
cout<<"panjang ekspresi "<<p<<endl;
for(i=0; i<=p; ++i)
{
s = eksp[i];
if (s == '{' || s == '[' || s == '(')
PUSH (S, s);
else if (s == '}' || s == ']' || s == ')')
{
t = POP(S);
switch (t)
{ case '{': t = '}'; break;
case '[': t = ']'; break;
case '(': t = ')'; break;
}
if (eksp[i] != t)
{ cout<<" Salah pasangan"<< endl;
return;
}
}
}

if (isEmpty() == 1)
cout<<"Pasangan tanda kurung sesuai"<<endl;
else
cout<<"Tanda kurung tidak berpasangan"<<endl;
}

int cek(char a, char b)


{
switch (a)
{
case '+': { if (b == '+' || b =='-' || b == '*' || b == '/' || b
=='^')
return(1);
else
return (0); // isi top of stack = '(' atau
empty
break;}
case '-':{ if (b == '+' || b =='-' ||b == '*' ||b == '/' || b
=='^')
return(1);
else
return (0);
break;}
case '*':{ if (b == '*' ||b == '/' || b =='^')
return(1);

Modul 9 : Struktur Data Stack - 86


Praktikum C++ Lanjut

else
return (0); // isi top of stack = '(' ||
'+'
break;} // || '-' || empty
case '/':{ if (b == '*' ||b == '/' || b =='^')
return(1);
else
return (0);
break;}
case '^':{ if (b == '^')
return(1);
else
return (0); // isi top of stack = '(' ||
'+'
break;} // || '-' || '*' || '/' || empty
}
}

void infix()
{
char eksp[N];
char postfix[N], x,y, Temp;
int i,j, p,t;
t = 0;
cout<<"Masukkan ekpresi Matematika = ";
cin>>eksp;
cout<<endl;
Inisialisasi();
p = strlen(eksp);
for(i=0 ; i<= p ; i++)
{
x = eksp[i];
if (x == '(')
PUSH(S,x);
else if (x =='+' || x =='-'|| x=='*'|| x =='/'|| x =='^')
{
y = TOP(S);
if (y == '#')
PUSH(S,x);
else
{ j = cek(x,y);
while (j == 1)
{
postfix[t]=POP(S);
t++;
y = TOP(S);
j = cek(x,y);
}
PUSH(S,x);
}
}
else if(x == ')')
{
Temp = POP(S);
while(Temp != '(')
{
postfix[t]=Temp;
t++;
Temp = POP(S);
}
}

Modul 9 : Struktur Data Stack - 87


Praktikum C++ Lanjut

else
{ postfix[t]= x ; // eksp[i] == operan
t++;
}
}
t--;
cout<<"Selesai ekspresi"<< endl;
p = isEmpty();
while (p != 1)
{
postfix[t]= POP(S);
t++;
p = isEmpty();
}
postfix[t]='\0';
cout<<" Persamaan postfix = "<<postfix<<endl;
}

char opr(char o, char a, char b)


{ //o adalah operator, a operan kiri, b operan kanan
int x, y,z;
char *c,*d,*e;
d = &a;
e = &b
x = atoi(d);
y = atoi(e);
switch (o)
{
case '+':{ z = x + y;
itoa(z,c,10);
break;
}
case '-':{ z = x - y;
itoa(z,c,10);
break;
}
case '*':{ z = x * y;
itoa(z,c,10);
break;
}
case '/':{ z = x / y;
itoa(z,c,10);
break;
}
case '^':{ z = x^y;
itoa(z,c,10);
break;
}
}
d = *c;
return(d);
}

void eval()
{
char eksp[N];
char ki, ka, x, y, Temp;
int i,j, p,t;
t = 0;
cout<<"Masukkan ekpresi postfix = ";
cin>>eksp;

Modul 9 : Struktur Data Stack - 88


Praktikum C++ Lanjut

cout<<endl;
Inisialisasi();
p = strlen(eksp);
for(i=0 ; i<= p ; i++)
{
x = eksp[i];
if (isdigit(x))
PUSH(S,x);
else if (x =='+' || x =='-'|| x=='*'|| x =='/'|| x =='^')
{
ka = POP(S);
ki = POP(S);
y = opr(x,ki,ka);
PUSH(S,y);
}
}
cout<<"Selesai ekspresi"<< endl;
Temp = POP(S);
if (isEmpty() == 1)
cout<<"Hasil evaluasi = "<<Temp<<endl;
else
cout<<"Persamaan postfix salah"<<endl;

void main()
{
// pasangan();
infix();
// eval();
}

Modul 9 : Struktur Data Stack - 89

Anda mungkin juga menyukai