Senin, 09 November 2015

QUEUE

Queue pada Struktur Data atau antrian adalah sekumpulan data yang mana penambahan elemen hanya bisa dilakukan pada suatu ujung disebut dengan sisibelakang(rear), dan penghapusan(pengambilan elemen) dilakukan lewat ujung lain (disebut dengan sisi depan atau front). 
Pada Stack atau tumpukan menggunakan prinsip“Masuk terakhir keluar pertama”atau LIFO (Last In First Out), Maka pada Queue atau antrian prinsip yang digunakan adalah “Masuk Pertama Keluar Pertama” atau FIFO (First In First Out).
Queue atau antrian banyak kita jumpai dalam kehidupan sehari-hari, ex: antrian Mobil diloket Tol, Antrian mahasiswa Mendaftar, dll.
Contoh lain dalam bidang komputer adalah pemakaian sistem komputer berbagi waktu(time-sharing computer system) dimana ada sejumlah pemakai yang akan menggunakan sistem tersebut secara serempak.
Pada Queue atau antrian Terdapat satu buah pintu masuk di suatu ujung dan satu buah pintu keluar di ujung satunya dimana membutuhkan variabel Head dan Tail ( depan/front, belakang/rear).
Karakteristik Queue atau antrian :
1. elemen antrian
2. front (elemen terdepan antrian)
3. tail (elemen terakhir)
4. jumlah elemen pada antrian
5. status antrian
Operasi pada Queue atau antrian
1. tambah(menambah item pada belakang antrian)
2. hapus (menghapus elemen depan dari antrian)
3. kosong( mendeteksi apakah pada antrian mengandung elemen atau tidak)
Operasi-operasi Queue :
1. Create()
Untuk menciptakan dan menginisialisasi Queue
Dengan cara membuat Head dan Tail  = -1
Queue pada Struktur Data
Queue pada Struktur Data


2. IsEmpty()
Untuk memeriksa apakah Antrian sudah penuh atau belum
Dengan cara memeriksa nilai Tail, jika Tail = -1 maka empty
Kita tidak memeriksa Head, karena Head adalah tanda untuk kepala antrian (elemen pertama dalam antrian) yang tidak akan berubah-ubah
Pergerakan pada Antrian terjadi dengan penambahan elemen Antrian kebelakang, yaitu menggunakan nilai Tail.
Queue pada Struktur Data

3. IsFull
Untuk mengecek apakah Antrian sudah penuh atau belum
Dengan cara mengecek nilai Tail, jika Tail >= MAX-1 (karena MAX-1 adalah batas elemen array pada C) berarti sudah penuh
Queue pada Struktur Data


4. Enqueue
Untuk menambahkan elemen ke dalam Antrian, penambahan elemen selalu ditambahkan di elemen paling belakang
Penambahan elemen selalu menggerakan variabel Tail dengan cara increment counter Tail terlebih dahulu
Queue pada Struktur Data

5. Dequeue()
Digunakan untuk menghapus elemen terdepan/pertama (head) dari Antrian
Dengan cara menggeser semua elemen antrian kedepan dan mengurangi Tail dgn 1
Penggeseran dilakukan dengan menggunakan looping.
Queue pada Struktur Data

6. Clear()
Untuk menghapus elemen-elemen Antrian dengan cara membuat Tail dan Head = -1
Penghapusan elemen-elemen Antrian sebenarnya tidak menghapus arraynya, namun hanya mengeset indeks pengaksesan-nya ke nilai -1 sehingga elemen-elemen Antrian tidak lagi terbaca
Queue pada Struktur Data

7. Tampil()
Untuk menampilkan nilai-nilai elemen Antrian
Menggunakan looping dari head s/d tail


STACK

STACK PADA STRUKTUR DATA 
Stack merupakan bagian dari struktur data yang dikategorikan ke dalam bentuk linear data, dimana operasi pemasukan maupun pengeluaran data selalu dilakukan pada salah satu sisinya[1]. Dalam dunia komputer, penggunaan stack (tumpukan) merupakan suatu hal yang umum digunakan seperti untuk penentuan alamat memory, penempatan ruang data dan aplikasi lain. Sebagai bagian dari struktur data, aplikasi stack juga digunakan untuk berbagai macam keperluan seperti pengujian kalimat palindrome, penguji tanda kurung (matching parentheses), dan juga berfungsi sebagai konversi dari notasi infix menjadi notasi postfix.

Pada perhitungan aritmatika, notasi infix adalah notasi yang menempatkan operator ditengah dua operand sedangkan notasi Postfix adalah notasi yang menempatkan operator setelah dua operand. Penggunaan notasi infixmerupakan hal yang lumrah digunakan dalam perhitungan aritmatika dibandingkan dengan penggunaan notasi Postfix, akan tetapi bagi mesin kompilasi notasi Postfix merupakan notasi yang digunakan untuk melakukan suatu perhitungan.

Tulisan ini dibuat untuk memberikan gambaran secara jelas proses simulasi konversi atas dua notasi aritmatika tersebut, berdasarkan studi literatur dari beberapa buku dan dituangkan dengan bantuan bahasa pemrograman Pascal. Adapun proses konversi ini ditujukan untuk menjelaskan bagaimana mesin kompilasi dapat merubah notasi infix yang biasa digunakan oleh berbagai kalangan menjadi notasi Postfix yang dimengerti oleh mesin kompilasi sehingga suatu proses perhitungan aritmatika dapat dilaksanakan oleh komputer. Alasan pemilihan bahasa pemrograman Pascal digunakan karena fleksibilitas bahasa tersebut dalam menerangkan implementasi dan aplikasi dari struktur data dalam bentuk pemrograman [2].
Definisi

Dalam dunia komputer, penggunaan stack atau tumpukan merupakan salah satu komponen penting untuk menjamin proses penanganan suatu data disamping hal lain seperti Queue (antrian), linked list, dan tree.

Definisi 1.

Stack adalah suatu koleksi atau kumpulan item data yang teroganisasi dalam bentuk urutan linear, yang operasi pemasukan dan penghapusan datanya dilakukan pada salah satu sisinya[1]

Definisi 2.

Diberikan suatu himpunan yang terurut himpunan sebagai S = {S1, S2, ......., ST}, T pada anggota S merupakan linear order, sehingga stack dari himpunan tersebut memiliki informasi sebagai berikut [1] :

1. Elemen puncak dari stack dalam himpunan S dikatakan sebagai TOPSleep, sehingga :

TOP[S} = ST ............................................................................(1)

2. Banyaknya elemen stack dalam himpunan S dikatakan sebagai NOELSleep, sehingga NOELSleep = T, dimana himpunan dari S tersebut dapat disusun sebagai :

S = {S1, S2, .........., SNOEL} .............................(2)

Dari dua definisi tersebut di atas maka suatu stack dapat digambarkan sebagai berikut :

1. Suatu stack dalam keadaan kosong akan memiliki informasi NOEL(S) = 0 dan TOP(S)= undefined.

clip_image002

S

2. Untuk stack yang bukan kosong, maka akan memiliki informasi seperti yang digambarkan di bawah ini dimana informasi yang ada adalah NOEL(S) = 1 dan TOP(S) = Merah



clip_image006

S

Untuk stack yang berisi lebih dari n jumlah data maka informasi yang ada pada stack tersebut berisikan NOEL(S) = 2 (jika berisi 2 data) dan TOP(S) = Biru seperti ditunjukan pada gambar di bawah ini :

clip_image008

S

Elemen-elemen yang berada dalam stack tersebut di atas, memiliki prinsip dasar dalam pengoperasiannya yaitu prinsip LIFO (Last In First Out) atau yang masuk paling belakang akan memiliki prioritas untuk keluar paling depan.

Suatu stack dapat digambarkan sebagai suatu array (larik) berdimensi satu yang elemen-elemennya berkisar antara 1 sampai n elemen. Dengan demikian jika suatu stack didefinisikan dengan n elemen maka dapat dikatakan jumlah maksimum dari stack atau NOEL(S) nya adalah n, sehingga penambahan elemen stack yang ke n+1 tidak diperkenankan atau stack tersebut dalam kondisi overflow. Hal tersebut juga berlaku untuk stack dengan nilai minimum yaitu NOEL(S) dari stack dalam kondisi 0, jika dilakukan operasi pengambilan elemen atas stack tersebut akan mengakibatkan stack tersebut dalam kondisi underflow. Dua kondisi tersebut merupakan dasar dalam merancang suatu aplikasi pemrograman komputer.
2.2. Operasi-operasi Stack

Dalam penggunaannya suatu stack memiliki beberapa operasi yang dapat diterapkan seperti membuat stack, penambahan eleme ke dalam stack, menghapusan elemen dari dalam stack, dan operasi lain yang berhubungan dengan stack tersebut. Adapun operasi-operasi dasar dari suatu stack adalah :

a) Create(Stack)

Operasi Create(Stack) digunakan untuk membuat suatu stack baru dengan nama stack, yang nilai elemen saat stack tersebut dibuat adalah NOEL(S) = 0, TOP(S) = NULL (tidak terdefinisikan)

b) IsEmpty(Stack)

Operasi ini merupakan operasi untuk mencek isi dari suatu stack dalam keadaan kosong atau berisi. Operasi ini memiliki 2 (dua) kondisi boolean yaitu :

a. True jika stack tersebut kosong atau dapat dikatakan NOEL(S) = 0

b.False jika stack tersebut tidak dalam kondisi kosong atau dapat dikatakan NOEL(S) > 0



c) Push(Stack, Elemen)

Operasi ini merupakan operasi untuk menambahkan satu elemen dengan nilai X pada puncak suatu stack, sehingga posisi TOP(S) akan bernilai X, penerapan operasi push pasa suatu stack S akan berakibat overflow jika NOEL(S) dari stack tersebut telah bernilai maksimum.



d) Pop(Stack)

Operasi ini berfungsi untuk menghapus satu elemen dari stack S, sehingga posisi NOEL(S) akan berkurang satu elemen, dan TOP(S) akan berubah. Operasi pop dapat menyebabkan kondisi underflow jika suatu stack S yang berada dalam kondisi minimum dikenakan operasi pop.


2.3. Notasi Infix dan Postfix

Suatu perhitungan aritmatika biasanya berhubungan dengan operand dan operator. Operand merupakan suatu karakter atau elemen yang nilainya dioperasikan dengan bantuan suatu operator untuik menghasilkan suatu solusi.

Misalkan jika diberikan suatu ekspresi aritmatika 2 * 3, maka elemen ‘dua’ dan elemen ‘tiga’ merupakan operand dari ekspresi tersebut dan elemen ‘*’ merupakan operator perkalian atas dua operand yang menghasilkan suatu solusi. Suatu ekspresi aritmatika dapat dibedakan dalam tiga bentuk notasi perhitungan yaitu :

1) Notasi prefix, jika operator ditempatkan sebelum dua operand

2) Notasi infix, jika operator ditempatkan diantara dua operand

3) Notasi postfix, jika operator ditempatkan setelah dua operand

Dalam penggunaannya, dalam kehidupan sehari-hari notasi infix merupakan notasi aritmatika yang paling banyak digunakan untuk mengekspresikan suatu perhitungan artimatik dibanding dengan dua notasi yang lain, akan tetapi notasi Postfix merupakan notasi yang digunakan oleh mesin kompilasi pada komputer dengan maksud untuk mempermudah proses pengkodean, sehingga mesin kompilasi membutuhkan stack untuk proses translasi ekspresi tersebut.
3. PEMBAHASAN
3.1.Konversi notasi infix ke postfix

Berdasarkan teori yang diterangkan tersebut di atas, proses konversi infix menjadi notasi Postfix dalam implementasinya membutuhkan stack pada proses konversinya, adapun proses tersebut memiliki 4 (empat) aturan yang digunakan, yaitu :

* Jika ditemukan simbol kurung buka “(“

Operasi push pada stack akan digunakan untuk menyimpan simbol tersebut ke dalam stack.

* Jika ditemukan simbol kurung buka “)”

Operasi pop digunakan untuk mengeluarkan operator-operator yang berada di dalam stack.

* Jika terdapat simbol operator

Jika dalam suatu untai notasi infix ditemukan simbol operator maka operasi yang dilakukan pada stack terbagi atas :

1. Jika TOP(S) dari stack tersebut kosong atau berisi simbol “(“ maka operasi push akan digunakan untuk memasukan operator tersebut pada posisi di TOP(S)
2. Jika operator yang berada dipuncak stack merupakan elemen yang memiliki tingkat yang sama atau lebih tinggi maka operasi pop digunakan untuk mengeluarkan operator tersebut diikuti operasi push untuk menyimpan operator hasil scanning untai.
3. Jika operator yang berada di puncak stack memiliki tingkat yang lebih rendah dari operator yang discan, maka operator baru akan langsung dimasukan ke dalam stack dengan operasi push.

Adapun tingkatan operator yang dilacak menurut urutan tingkat adalah :

Tabel 1. Level Operator dalam stack
Operator Level Operator dalam stack
** Tertinggi
* atau / Menengah
+ atau - Rendah

4. Jika ditemukan suatu operand

Nilai operand yang ada langsung dijadikan output dari notasi Postfix.

Dicontohkan dalam suatu aplikasi suatu ekspresi aritmatika dalam notasi infix sebagai berikut

((A * B) + C / D – E ** F) * G;

Ekspresi tersebut di atas, dikonversikan ke dalam bentuk notasi Postfix digambarkan sebagai berikut :
Indeks urutan ke- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Karakter-karakter yang akan dilacak dalam notasi infix
( ( A * B ) + C / D - E ** F ) * G ;
Operator puncak (TOP(S) ( (
( (
( *
(
( *
(
( ( +
( +
( /
+
( /
+
( -
( -
( **
-
( **
-
( * *
Output yg dihasilkan dalam bentuk postfix A B * C D / + F ** - G *

o Karakter-karakter yang akan dilacak dalam notasi infix
o Output yang dihasilkan dalam notasi Postfix

Dari contoh untai tersebut di atas, maka hasil konversi dari notasi infix menjadi notasi Postfix menghasilkan untai : A B * C D /+ E F **- G *
3.2. Implementasi algoritma Stack

Pada bahasa pemrograman PASCAL suatu stack didefinisikan dalam bentuk algoritma, hal ini dimaksudkan untuk mendapatkan hasil yang optimal dan terarah saat program tersebut di rancang dan digunakan. Dari teori tentang penggunaan stack dalam struktur datasebelumnya, suatu stack memiliki dua informasi penting yaitu adanya TOP(S) yang berisikan informasi isi untai dalam bentuk karakter dan NOEL(S) yang berisikan informasi jumlah untai yang bernilai integer dari stack tersebut.

Pada implementasinya, kedua informasi tersebut dikemas dalam bentuk record yang memuat array (larik) untuk membatasi isi dari stack, dan memberikan nilai indeks atas informasi yang masuk dalam stack tersebut pada saat dilakukan operasi. Adapun secara algoritma stack tersebut di bentuk sebagai :

Const

NoelStack = 80;

Type

Eon = Char;

Stack = Record

Top : Array [ 1 .. NoelStack] of Eon;

Noel : 0 .. NoelStack;

End;

Dari algoritma tersebut di atas, isi dari stack dapat menampung 80 karakter yang dikemas dalam bentuk record dengan nama stack.

Setelah algoritma yang memuat informasi dasar dari stack didefinisikan, pembentukan algoritma untuk operasi terhadap stack dapat disusun dalam bentuk prosedur dan fungsi yang dibuat sendiri. Adapun algoritma yang digunakan untuk operasi suatu stack adalah :

1) Algoritma Create(S)

Algoritma ini memuat suatu prosedur untuk membuat stack, yang memberikan kondisi noel dari stack akan bernilai nol dan top dari stack tersebut belum dapat didefinisikan, sehingga implementasi dari algoritma create stack adalah ;

Procedure Create(var S : Stack);

Begin

S.Noel := 0;

End;

2) Algoritma IsEmpty(S)

Algoritma untuk operasi Isempty memberikan informasi Boolean yaitu kondisi benar (true) atau salah (False), sehingga pada implementasinya algoritma ini menggunakan fungsi yang dibuat sendiri, yang terimplementasi sebagai berikut :

Function IsEmpty(Var S : Stack) : Boolean;

Begin

IsEmpty := S.Noel = 0

End;

3) Algoritma Push(S, E)

Dalam merancang algoritma untuk operasi push dimulai dengan melakukan pengecekan atas isi dari stack tersebut dalam keadaan penuh atau tidak. Kondisi stack dalam keadaan maksimum akan mengakibatkan overflow pada stack tersebut sehingga prosedur error trapping perlu didefinisikan untuk mencegah terjadinya overflow condition tersebut. Adapun implementasi dari algoritma push tersebut adalah :

Procedure Push(Var S : Stack; TipeBAru : Eon);

Begin

If S.Noel = NoelStack Then

Stackerror(1)

Else

Begin

S.Noel := S.Noel + 1;

S.Top[S.Noel] := TipeBaru

End

End;

4) Algoritma Pop(S)

Operasi terakhir dari stack adalah operasi pop yang berfungsi untuk mengeluarkan isi dari dalam stack. Seperti halnya operasi push, pada operasi pop penggunaan error trapping dipakai untuk mencek kondisi underflow yaitu kondisi stack kosong yang dikenakan operasi pop. Algoritma dari pop ini adalah :

Procedure Pop(Var S : Stack; Var NilaiStack : Eon);

Begin

If S.Noel = 0 Then

StackError(2)

Else

Begin

NilaiStack := S.Top[s.Noel];

S.Noel := S.Noel -1

End

End;

Penggunaan error trapping untuk operasi push dan pop didefinisikan lebih lanjut dalam algoritma stackerror yang digunakan untuk menentukan kondisi overflow atau underflow suatu stack. Adapun algoritma dari error trapping ini adalah ;

Procedure StackError(TingkatanError : Integer);

Begin

Case TingkatanError of

1 : WriteLn(‘Isi Stack sudah penuh... kondisi overflow’);

2 : WriteLn(‘Isi Stack Kosong ... kondisi underflow’)

End

End;

3.3.Implementasi Proses Konversi Notasi Infix ke NotasiPostfix

Dari operasi dasar yang dapat diterapkan pada suatu stack tersebut, tahap kedua dari pelaksanaan konversi notasi infix ke notasi Postfix adalah merancang bangun algoritma proses konversi, dengan cara melakukan perbandingan isi operator yang berada di dalam stack dengan operator yang dibaca untuk dimasukan dalam stack. Adapun proses perbandingan tersebut di lihat berdasarkan tingkatan operator yang tertuang dalam tabel berikut :

Tabel 3. Perbandingan Operator dalam stack dan operator yang dibaca

Operator


Nilai operator dalam stack


Nilai operator yang dibaca

)





0

(


0


5

+,-


2


1

*,/


4


3



Berdasarkan tabel tersebut suatu operator yang dibaca dan akan dimasukan ke dalam stack, terlebih dahulu melalui proses perbandingan nilai dengan operator yang ada di dalam stack sebelumnya. Dalam arti kata lain jika nilai dari operator yang berada dalam stack lebih besar dari nilai operator yang dibaca maka operator yang berada di dalam stack akan dikeluarkan sampai nilai tersebut sama atau lebih kecil. Implementasi dari algoritmanya dapat dijabarkan dalam bentuk fungsi sebagai berikut :

Function IsiDlmStack(Operator : Char) : Integer;

Begin

Case Operator Of

‘(‘ : IsiDlmStack := 0;

‘+‘,’-‘ : IsiDlmStack := 2;

‘*‘,’/’ : IsiDlmStack := 4;

End

End;

Fungsi Isidlmstack tersebut di atas merupakan fungsi level operator yang posisinya berada dalam suatu stack, adapun fungsi untuk menentukan level operator yang dibaca adalah :

Function Stackyangdibaca(Operator : Char) : Integer;

Begin

Case Operator Of

‘)‘ : Stackyangbaca := 0;

‘+‘,’-‘ : Stackyangbaca := 1;

‘*‘,’/’ : Stackyangbaca := 3;

‘(‘ : Stackyangbaca := 5

End

End;

Setelah fungsi pengecekan dilakukan, proses yang perlu dirancang selanjutnya adalah membentuk suatu prosedur untuk menyimpan operator yang dibaca ke dalam suatu susunan array yang implementasinya dibuat sebagai berikut :

Procedure SimpanChar(Ch : Char;

Var Ekspost : TipeEks;

Var Indekspost : TipeIndex);

Begin

Indekspost :=Indekspost + 1;

Ekspost := ch

End;

Dengan adanya prosedur penyimpanan operator ke dalam suatu array tersebut di atas, maka proses konversi notasi infix ke notasi Postfix disusun dalam bentuk bahasa algoritma sebagai berikut[2] :

Prosedur KonversiInfixKePostfix

1. Read Panjang suatu untai karakter

2. Create Stack

3. Push Operator ‘(‘ ke Puncak Stack

4. n := 0

5. For K := 1 To Panjang suatu untai + 1 do

If untai ke k adalah operand then

Keluarkan untai ke K dalam bentuk Output

Else

While Nilai operator dal;am stack > operator yang dibaca do

Pop Isi operator dari dalam stack

Keluarkan operator tersebut dalam bentuk output

End While

If Operator ke K = ‘)’ then

Pop isi operator dari stack

Else

Push Operator ke dalam stack

End If

End If

Panjang untai ;= n

6. End For

Dengan berpandangan pada algoritma konversi tersebut di atas, rancang bangun algoritma dalam baha pemrograman Pascal disusun sebagai berikut :

Procedure konversi infixkePostfix (eks dlm : Tipe eks;

pjg dlm : Tipe index;

var ekspost: Tipe Eks;

var panjang post : Tipe indeks);

Var

opstack : stack ;

indeksdlm, indeks post: Tipe index;

chdlm, operator, simpan : char ;

Begin

create (Opstack);

Push (Opstack, '(');

eksdlm[pjg dlm +1] := ')';

Indeks post: = 0;

For indeksdlm : = 1 to pjgdlm +1 Do

Begin

chdlm: = Eks Dlm [indeks dlm];

if ch dlm in ['A'....'Z'] then

simpan char (ch Dlm, Ekspost,indekspost)

Else

Begin

While isidlmstack(puncak stack (opstack))> stack yang dibaca (ch dlm) Do

begin

pop(opstack,operator);

simpanchar(operator,ekspost,indekspost)

end;

if chdlm = ')' then

pop(opstack,simpan)

else

push(opstack,simpan)

end

panjang post := indekspost

end;

panjang post := indekspost

end;

Sajian lengkap dari proses konversi notasi infix ke notasi Postfix dalam bahasa Pascal yang siap untuk diterapkan diuraikan di bawah tulisan ini


4. KESIMPULAN

Aplikasi konversi notasi infix ke notasi Postfix merupakan salah satu sarana untuk dapat mengetahui proses perhitungan aritmatika dalam mesin kompilasi. Penggunaan stack tersebut juga dapat dipakai untuk metode lain seperti membuat matching parentheses, maupun uji palindrome disamping penggunaannya dalam proses konversi notasi ini, yang perlu dipahami adalah suatu stack pada dasarnya merupakan array yang memuat 2 informasi penting yaitu NOEL yang berfungsi untuk mengetahui jumlah tumpukan dan TOP yang berfungsi untuk menentukan posisi puncak dari suatu stack. Stack juga memiliki 2 kondisi yang dapat menyebabkan error yaitu kondisi underflow jika stack tersebut dalam keadaan kosong dilakukan operasi ambil data (pop) dan kondisi overflow jika stack dalam keadaan penuh dilakukan operasi penambahan data. Kedua posisi ini dapat menyebabkan stack dalam keadaan tidak valid sehingga penggunaan error trapping untuk menampung kondisi tidak valid perlu diperhatikan.

Notasi infix yang umum digunakan oleh berbagai kalangan dalam melakukan suatu proses perhitungan aritmatika dapat *** disusun ke dalam notasi Postfix yang digunakan oleh mesin kompilasi sehingga pengetahuan tentang penggunaan notasi aritmatika akan lebih luas.


DAFTAR PUSTAKA

[1] LOOMIS, Mary E.S., Data Management and File Processing, Prentice-Hall, Inc., Englewood Cliffs, New Jersey, 1985.

[2] HOROWITZ, E and Sahni S.,Fundamental of Computer Algorithms, Computer Science Press, Potomac, Maryland, 1978.

[3] MCCRACKEN, Daniel D.,A Second Course in Computer Science with Pascal, John Willey & Sons, City College, New York, 1989



Listing Program

{ Program Name : Konversi.Pas

Authors : Oke Hendradhy

Version : 1.0

}



Uses crt;

const

Noelstack = 80;

Makschar = 80;



Type

Eon = char;

stack = Record

Top : array[1...Noelstack] of Eon;

Noel : 0... Noelstack;

End;

Tipeindex = 0... makschar;

Typeeks = array[1... Noelstack] of char



Var

lagi : char;

{Bentuk-bentuk operasi stack}



Function isempty(Var s : stack):Boolean;

Begin

IsEmpty : = s. noel = 0

End;



Procedure create (var s. stack);

Begin

S. Noel : = 0;

End;



procedure buatkosong (Var s. stack);

Begin

S. Noel : = 0;

End ;



Procedure stack Error (tingkat Error: integer);

Begin

Case tingkat error of

1 : Writeln (isi stack sudah terlalu penuh);

2 : Writeln (isi stack kosong);

End

End;



Procedure push( var s : stack; tipebaru : Eon);

Begin

If s. Noel = Noel stack then

stack Error(1)

Else

Begin

s.Noel : = s. Noel+1 ;

s.Top[s.Noel] : = tipebaru

End

End;





Procedure pop(var s: stack ;

var nilaistack : Eon);

Begin

If s. Noel = 0 then

Stack error(2)

Else

Begin

Nilaistack : = s.top[s.Noel];

S.Noel : = s. Noel - 1;

End

End;



{proses konversi suatu ekspresi}

Function puncak stack(s : stack) : Eon;

Begin

Puncak stack : = s.top[s.noel]

End;





Function isidlmstack (operator: char); integer;

Begin

case operator of

'(' : isidlmstack : = 0;

'+','-' : isidlmstack : = 2;

'*',','/' : isidlmstack : = 4;

End

End;



Function stackyangdibaca (operator : char): integer

Begin

Case operator of

')' : stackyangdibaca : =0;

'+','-' : stackyangdibaca : = 1;

'*','/' : stackyangdibaca : = 3;

'(' : stackyangdibaca : = 5;

End

End;

Procedure simpanchar(ch:char; Var ekspost : Tipeks;Var indekspost ; Tipeindex);

Begin

Indekspost : = indeks post+1;

ekspost [indekspost]: = ch;

End;



Procedure konversi infixkePostfix (eks dlm : Tipe eks;

pjg dlm : Tipe index;

var ekspost: Tipe Eks;

var panjang post : Tipe indeks);

Var

opstack : stack ;

indeksdlm, indeks post: Tipe index;

chdlm, operator, simpan : char ;



Begin

create (Opstack);

Push (Opstack, '(');

eksdlm[pjg dlm +1] := ')';

Indeks post: = 0;

For indeksdlm : = 1 to pjgdlm +1 Do

Begin

chdlm: = Eks Dlm [indeks dlm];

if ch dlm in ['A'....'Z'] then

simpan char (ch Dlm, Ekspost,indekspost)

Else

Begin

While isidlmstack(puncak stack (opstack))> stack yang dibaca (ch dlm) Do

begin

pop(opstack,operator);

simpanchar(operator,ekspost,indekspost)

end;

if chdlm = ')' then

pop(opstack,simpan)

else

push(opstack,simpan)

end

panjang post := indekspost

end;

panjang post := indekspost

end;





produce konversi ekspresi;

var

indeks panjangdlm, panjang post :tipe index;

eksdlm,ekspot :tipe eks



begin

lagi :='y';

While (upcase(lagi) ='x' do

Begin

clsscr;

panjangdlm := 0

while not eoln do

begin

panjangdlm:=panjangdlm +1;

read(eksdlm[panjangdlm])

end;

readln ;

write('ekspresi infix:');

for index := 1 to panjangdlm do

write(eksdlm[index]);

writeln;

konversiinfixkePostfix(eksdlm, panjangdlm, ekspost, panjang post);

write ('dalam bentuk Postfix')

for indeks := 1 to panjangpost do

write (ekspost [indeks]);

writeln;

writeln;

write ('ada data lagi.'); readln (lagi)

end;

End;


LINK LIST



B. Linked List
Linked List

Linked List adalah salah satu bentuk struktur data, berisi kumpulan data
(node) yang tersusun secara sekuensial, saling sambungmenyambung,
dinamis dan terbatas.
- Linked List sering disebut juga Senarai Berantai
- Linked List saling terhubung dengan bantuan variabel pointer
- Masing-masing data dalam Linked List disebut dengan node (simpul) yang
menempati alokasi memori secara dinamis dan biasanya berupa struct
yang terdiri dari beberapa field.
 

Single Linked List adalah sebuah LINKED LIST yang menggunakan sebuah variabel pointer saja untuk menyimpan banyak data dengan metode LINKED LIST, suatu daftar isi yang saling berhubungan.
Ilustrasi single LINKED LIST:

Pada gambar di atas, data terletak pada sebuah lokasi dalam sebuah memory, tempat yang disediakan memory untuk menyimpan data disebut node ? simpul, setiap node memiliki pointer ( penunjuk ) yang menunjuk ke node berikutnya sehingga terbentuk suatu untaian yang disebut single LINKED LIST. Bila dalam single LINKED LIST pointer hanya dapat bergerak ke satu arah saja, maju / mundur, kanan / kiri, sehingga pencarian datanya juga hanya satu arah saja.

Ada 2 Tipe Single Linked List yaitu
·         Single Linked List Circular
·         Single Linked List Non Circular


1.     Single Linked List Circular
Single Linked List Circular adalah Single Linked List yang pointer nextnya menunjuk pada dirinya sendiri. Jika Single Linked List tersebut terdiri dari beberapa node,
maka pointer next pada node terakhir akan menunjuk ke node terdepannya.
Pengertian:
Single : artinya field pointer-nya hanya satu buah saja dan satu arah.
Circular : artinya pointer next-nya akan menunjuk pada dirinya sendiri sehingga berputar

Ilustrasi Single Linked List Circular
- Setiap node pada linked list mempunyai field yang berisi pointer ke node
  berikutnya, dan juga memiliki field yang berisi data.
- Pada akhir linked list, node terakhir akan menunjuk ke node terdepan
  sehingga linked list tersebut berputar. Node terakhir akan menunjuk lagi
  ke head.

PEMBUATAN SINGLE LINKED LIST CIRCULAR
Deklarasi node
Dibuat dari struct berikut ini:
typedef struct TNode{
int data;
TNode *next;
};

Penjelasan:
- Pembuatan struct bernama TNode yang berisi 2 field, yaitu field data
  bertipe integer dan field next yang bertipe pointer dari TNode
- Setelah pembuatan struct, buat variabel haed yang bertipe pointer dari
  TNode yang berguna sebagai kepala linked list.

  Pembentukan node baru
Digunakan keyword new yang berarti mempersiapkan sebuah node baru
berserta alokasi memorinya.

TNode *baru;
baru = new TNode;
baru->data = databaru;
baru->next = baru;

SINGLE LINKED LIST CIRCULAR MENGGUNAKAN HEAD
- Dibutuhkan satu buah variabel pointer: head
- Head akan selalu menunjuk pada node pertama

Deklarasi Pointer Penunjuk Kepala Single Linked List
Manipulasi linked list tidak bisa dilakukan langsung ke node yang dituju,
melainkan harus melalui node pertama dalam linked list. Deklarasinya sebagai berikut:

TNode *head;

Fungsi Inisialisasi Single LinkedList
void init(){
head = NULL;
}

Function untuk mengetahui kosong tidaknya Single LinkedList
int isEmpty(){
if(head == NULL) return 1;
else return 0;
}

PENAMBAHAN DATA
Penambahan data di depan
Penambahan node baru akan dikaitan di node paling depan, namun pada saat
pertama kali (data masih kosong), maka penambahan data dilakukan pada
head nya.
Pada prinsipnya adalah mengkaitkan data baru dengan head, kemudian head
akan menunjuk pada data baru tersebut sehingga head akan tetap selalu
menjadi data terdepan. Untuk menghubungkan node terakhir dengan node
terdepan dibutuhkan pointer bantu.

void insertDepan(int databaru){
TNode *baru,*bantu;
baru = new TNode;
baru->data = databaru;
baru->next = baru;

if(isEmpty()==1){
head=baru;
head->next=head;
}
else {
bantu = head;
while(bantu->next!=head){
bantu=bantu->next;
}
baru->next = head;
head = baru;
bantu->next = head;
}
cout<<"Data masuk\n";
}

Penambahan data di belakang Penambahan data dilakukan di belakang, namun pada saat pertama kali data langsung ditunjuk pada head-nya. Penambahan di belakang lebih sulit karena kita membutuhkan pointer bantu untuk mengetahui data terbelakang, kemudian dikaitkan dengan data baru. Untuk mengetahui data terbelakang perlu digunakan perulangan.

void insertBelakang (int databaru)
{
TNode *baru,*bantu;
baru = new TNode;
baru->data = databaru;
baru->next = baru;
if(isEmpty()==1){
head=baru;
head->next=head;
}
else {
bantu = head;
while(bantu->next != head){
bantu=bantu->next;
}
bantu->next = baru;
baru->next = head;
}
cout<<"Data masuk\n";
}

“Bagaimana dengan penambahan di tengah?”

MENAMPILKAN DATA
Function untuk menampilkan isi single linked list
void tampil(){ TNode *b;
b = head;
if(isEmpty()==0)
{
do
{
cout<data<<" ";
b=b->next;
}
while(b!=head);
cout<<<"Masih kosong\n";
}

- Function di atas digunakan untuk menampilkan semua isi list, di mana linked list ditelusuri satu-persatu dari awal node sampai akhir node. Penelusuran ini dilakukan dengan menggunakan suatu variabel node bantu, karena pada prinsipnya variabel node head yang menjadi tanda awal list tidak boleh berubah/berganti posisi.
- Penelusuran dilakukan terus sampai node terakhir ditemukan menunjuk ke head lagi. Jika belum sama dengan head, maka node bantu akan berpindah ke node selanjutnya dan membaca isi datanya dengan menggunakan field next sehingga dapat saling berkait.
- Jika head masih NULL berarti data masih kosong!

PENGHAPUSAN DATA
Function untuk menghapus data terdepan

void hapusDepan ()
{ TNode *hapus,*bantu;
if (isEmpty()==0)
{
int d;
hapus = head; d = head->data;
if(head->next != head){
bantu = head;
while(bantu->next!=head){
bantu=bantu->next;
}
head = head->next;
delete hapus;
bantu->next = head;
}else{
head=NULL;
}
cout<<<" terhapus\n";
}
else cout<<"Masih kosong\n";
}

- Function di atas akan menghapus data teratas (pertama) yang ditunjuk oleh head  pada linked list
- Penghapusan node tidak boleh dilakukan jika keadaan node sedang ditunjuk oleh pointer, maka harus ditampung dahulu pada variabel hapus dan barulah kemudian menghapus variabel hapus dengan menggunakan perintah delete.
- Sebelum data terdepan dihapus, head harus ditunjukkan ke data sesudahnya  terlebih dahulu sehingga data setelah head lama akan menjadi head baru (data terdepan yang baru).
- Jika head masih NULL maka berarti data masih kosong!

Penghapusan data di belakang:

void hapusBelakang()
{ TNode *hapus,*bantu;
if (isEmpty()==0)
{
int d;
hapus = head;
if(head->next == head){
head = NULL;
}
else
{
bantu = head;
while(bantu->next->next != head){
bantu = bantu->next;
}
hapus = bantu->next;
d = bantu->data;
bantu->next = head;
delete hapus;
}
cout<<<" terhapus\n";
}
else
cout<<"Masih kosong\n";
}

- Membutuhkan pointer bantu dan hapus.
- Pointer hapus digunakan untuk menunjuk node yang akan dihapus, dan pointer bantu digunakan untuk menunjuk node sebelum node yang dihapus.
- Pointer bantu akan digunakan untuk menunjuk ke nilai NULL.
- Pointer bantu akan selalu bergerak bersama dengan pointer hapus tapi letak pointer bantu harus selalu dibelakang pointer hapus.

Function untuk menghapus semua elemen Linked List

void clear(){ TNode *bantu,*hapus;
bantu = head;
while(bantu->next!=head){
hapus = bantu;
bantu = bantu->next;
delete hapus;
}
head = NULL;
}

SINGLE LINKED LIST MENGGUNAKAN HEAD DAN TAIL
- Dibutuhkan dua buah variabel pointer: head dan tail
- Head akan selalu menunjuk pada node pertama, sedangkan tail akan
selalu menunjuk pada node terakhir.

Inisialisasi LinkedList

TNode *head, *tail;

Fungsi Inisialisasi LinkedList

void init(){
head = NULL;
tail = NULL;
}

Function untuk mengetahui kosong tidaknya LinkedList

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

PENAMBAHAN DATA
Pengkaitan node baru ke linked list di depan
Penambahan data baru di depan akan selalu menjadi head.

void insertDepan(int databaru){
TNode *baru;
baru = new TNode;
baru->data = databaru;
baru->next = baru;
if(isEmpty()==1){
head=baru;
tail=baru;
head->next=head;
tail->next=tail;
}
else {
baru->next = head;
head = baru;
tail->next = head;
}
cout<<"Data masuk\n";
}

Penambahan Data di belakang Pada penambahan data di belakang, data akan selalu dikaitkan dengan tail, karena tail terletak di node paling belakang. Setelah dikaitkan dengan node baru, maka node baru tersebut akan menjadi tail.

void tambahBelakang(int databaru){ TNode *baru;
baru = new TNode;
baru->data = databaru;
baru->next = baru;
if(isEmpty()==1){
head=baru;
tail=baru;
head->next=head;
tail->next=tail;
}
else
{
tail->next = baru;
tail = baru;
tail->next = head;
}
cout<<"Data masuk\n";
}

Kelebihan dari Single Linked List dengan Head & Tail adalah pada penambahan data di belakang, hanya dibutuhkan tail yang mengikat node baru saja tanpa harus menggunakan perulangan pointer bantu.

Function untuk menampilkan isi linked list:

void tampil(){ TNode *b;
b = head; if(isEmpty()==0)
{
do
{ cout<data<<" ";
b=b->next;
}
while(b!=tail->next);
cout<<<"Masih kosong\n";
}

Pada prinsipnya sama dengan function tampil sebelumnya.

Function untuk menghapus data di depan

void hapusDepan(){ TNode *hapus;
if (isEmpty()==0){ int d;
hapus = head;
d = head->data;
if(head != tail){
hapus = head;
head = head->next;
tail->next = head;
delete hapus;
}else{
head=NULL;
tail=NULL;
}
cout<<<" terhapus\n";
}
else cout<<"Masih kosong\n";
}

- Function di atas akan menghapus data terdepan (pertama) yang ditunjuk oleh head pada linked list
- Penghapusan node tidak boleh dilakukan jika keadaan node sedang ditunjuk oleh pointer, maka harus dilakukan penunjukkan terlebih dahulu dengan variabel hapus pada head, kemudian dilakukan pergeseran ke node berikutnya sehingga data setelah head menjadi head baru, kemudian menghapus variabel hapus dengan menggunakan perintah delete.
- Jika tail masih NULL maka berarti data masih kosong!

Function untuk menghapus data di belakang:

Dengan menggunakan Single Linked List ber-Head dan Tail, pengahapusan data di belakang akan mudah dilakukan, tidak seperti pada Single Linked List hanya ber-Head saja.

void hapusBelakang(){ TNode *hapus,*bantu;
if (isEmpty()==0){ int d;
if(head == tail){ d = tail->data;
head = NULL;
tail = NULL;
}
else
{
bantu = head;
while(bantu->next != tail){
bantu = bantu->next;
}
hapus = tail;
tail = bantu;
d = hapus->data;
tail->next = head;
delete hapus;
}
cout<<<" terhapus\n";
}
else cout<<"Masih kosong\n";
}

- Function di atas akan menghapus data terbelakang (terakhir) yang ditunjuk oleh tail pada linked list
- Penghapusan node tidak boleh dilakukan jika keadaan node sedang ditunjuk oleh pointer, maka harus dilakukan penunjukkan terlebih dahulu dengan variabel hapus pada tail, kemudian dibutuhkan pointer bantu untuk membantu pergeseran dari head ke node berikutnya sampai sebelum tail, sehingga tail dapat ditunjukkan ke bantu tersebut, dan bantu tersebut akan menjadi tail yang baru. Setelah itu hapus variabel hapus dengan menggunakan perintah delete.
- Jika tail masih NULL maka berarti data masih kosong!

Function untuk menghapus semua elemen LinkedList

void clear(){ TNode *bantu,*hapus;
if(isEmpty() == 0){ bantu = head;
while(bantu->next!=head){
hapus = bantu;
bantu = bantu->next;
delete hapus;
}
head = NULL;
tail = NULL;
}
}

- Menggunakan pointer bantu yang digunakan untuk bergerak sepanjang
list, dan menggunakan pointer hapus yang digunakan untuk menunjuk
node-node yang akan dihapus.
- Pada saat pointer hapus menunjuk pada node yang akan dihapus, pointer
bantu akan bergerak ke node selanjutnya, dan kemudian pointer hapus
akan didelete.

2.  Single Linked List Non Circular
Pengertian:
Single : artinya field pointer-nya hanya satu buah saja dan satu arah.
Linked List : artinya node-node tersebut saling terhubung satu sama lain.
Ilustrasi Linked List
- Setiap node pada linked list mempunyai field yang berisi pointer ke node
berikutnya, dan juga memiliki field yang berisi data.
- Pada akhir linked list, node terakhir akan menunjuk ke NULL yang akan
digunakan sebagai kondisi berhenti pada saat pembacaan isi linked list

Contoh program single linked list non circular tambah list di depan :
# include<stdio.h>
# include<stdlib.h>
# include<conio.h>
# include<iostream.h>
# include<ctype.h>
# include<string.h>

struct simpul
{
            int angka;
            struct simpul*berikut;
} ;

struct simpul *awal=NULL;
int bil;

void tambah_list_didepan(int info);
void isi_list();
void tampil_list();
void hapus_list();

void main ()

{

            clrscr();
            isi_list();
            clrscr();
            tampil_list();
            hapus_list();
            getch();
}
void tambah_list_didepan(int info)
{
            struct simpul *baru;
            baru=(struct simpul *)malloc(sizeof(struct simpul));
            baru->angka=info;

            baru->berikut=awal;


            awal=baru;
}

void isi_list()
{
            char jawab;
            do
            {
            clrscr();
            cout<<"\ninput bilangan :";
            cin>>bil;
            tambah_list_didepan(bil);
            cout<<"\ntambah data Y/T :"  ;
            cin>>jawab;
            }
            while (toupper(jawab)!='T');

}
void tampil_list()
{
            struct simpul* baca;
            int i;
            baca=awal;
            i=1;

            while(baca!=NULL)

            {
                        cout<<"\nbilangan ke-"<<i<<"yang dibaca :"<<baca->angka;
                        i++;
                        baca=baca->berikut;
            }

}

void hapus_list()

{
            struct simpul*hapus;
            hapus=awal;
            while(hapus!=NULL)
            {
                        awal=hapus->berikut;
                        free(hapus);
                        hapus=awal;
            }
}

Contoh program single linked list non circular tambah di belakang :
#include <stdio.h>
#include <stdlib.h>
#include <constream.h>
#include <ctype.h>
#include <string.h>

struct siswa
{
 char nrp[8],nama[20];
 int umur;
 float ipk;
};

struct simpul
{
 char nrp[8],nama[20];
 int umur;
 float ipk;
 struct simpul *berikut;
};

struct simpul *awal = NULL, *akhir = NULL;
struct siswa mhs;

void tambah_list_dibelakang(struct siswa info);
void isi_list();
void tampil_list();
void hapus_list();

void main()
{
 clrscr();
 isi_list();
 clrscr();
 tampil_list();
 hapus_list();
 getch();
}

void tambah_list_dibelakang(struct siswa info)
{
 struct simpul *baru;

 baru = (struct simpul *) malloc(sizeof(struct simpul));
 strcpy (baru -> nrp,info.nrp);
 strcpy (baru -> nama,info.nama);
 baru -> umur = info.umur;
 baru -> ipk  = info.ipk;

 if (awal == NULL)
 {
  awal = baru;
 }
 else
 {
  akhir -> berikut = baru;
 }
 akhir = baru;
 akhir -> berikut = NULL;
}

void isi_list()
{
 char jawab;

 do
 {
  clrscr();
  cout<<"NRP   : ";cin>>mhs.nrp;
  cout<<"Nama  : ";cin>>mhs.nama;
  cout<<"Umur  : ";cin>>mhs.umur;
  cout<<"IPK   : ";cin>>mhs.ipk;
  tambah_list_dibelakang(mhs);
  cout<<"\nTambah Data [Y/T]? : ";
  cin>>jawab;

 }
 while (toupper(jawab) != 'T');
}

void tampil_list()
{
 struct simpul *baca;
 int i;

 baca = awal;
 i = 1;

 while (baca != NULL)
 {
  cout<<"Data Ke : "<<i<<endl;
  cout<<"NRP     : "<<baca -> nrp<<endl;
  cout<<"Nama    : "<<baca -> nama<<endl;
  cout<<"Umur    : "<<baca -> umur<<endl;
  cout<<"IPK     : "<<baca -> ipk<<endl;
  cout<<endl;
  i++;
  baca = baca -> berikut;
 }
}

void hapus_list()
{
 struct simpul *hapus;

 hapus = awal;
 while (hapus != NULL)
 {
  awal = hapus -> berikut;
  free (hapus);
  hapus = awal;
 }
}

Contoh program single linked list non circular tambah list ditengah :
#include <stdio.h>
#include <constream.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

struct siswa
{
 char nama[20];
 int umur;

};

struct simpul
{
 char nama[20];
 int umur;

 struct simpul *berikut;
};

struct simpul *awal=NULL,*akhir=NULL;
struct siswa mhs;

void tambah_list_belakang(struct siswa info);
void isi_list();
void sisip_list(struct simpul *first,struct siswa info,char posisi[20]);
void sisip_isi_list();
void tampil_list();
void hapus_list();

void main()
{
 clrscr();
 isi_list();

 clrscr();
 tampil_list();
 sisip_isi_list();
 tampil_list();
 hapus_list();
 getch();
}

void tambah_list_dibelakang(struct siswa info)
{
 struct simpul *baru;

 baru=(struct simpul*)malloc(sizeof(struct simpul));
 strcpy(baru->nama,info.nama);
 baru->umur=info.umur;

 if (awal==NULL)
  {
   awal=baru;
  }
 else
  {
   akhir->berikut=baru;
  }
 akhir=baru;

 akhir ->berikut=NULL;
}

void isi_list()
{
 char jawab;

 do
 {
  clrscr();
  cout<<"Nama: ";gets(mhs.nama);
  cout<<"Umur: ";cin>>mhs.umur;

  tambah_list_dibelakang(mhs);

  cout<<"\nTambah Data [Y/T]: ";
  cin>>jawab;
 }
 while (toupper(jawab)!='T');
}
void sisip_list(struct simpul *first,struct siswa info,char posisi[20])
{
struct simpul *bantu,*baru;

baru = new simpul;
strcpy(baru->nama,info.nama);
baru->umur=info.umur;
bantu=first;

do
{
if (strcmp(posisi,bantu->nama)!=0)  {bantu=bantu->berikut;}
}
while (bantu!=NULL && strcmp(posisi,bantu->nama)!=0);

baru->berikut=bantu->berikut;
bantu->berikut=baru;
}


void sisip_isi_list()
{
char cari[20];
struct siswa ganti;

cout<<"\nInput Data Baru :";
cout<<"\nNama :";gets(ganti.nama);
cout<<"\nUmur :";cin>>ganti.umur;
cout<<"\n";
cout<<"\nData Akan Disisipkan Setelah Nama: ";
gets(cari);
sisip_list(awal,ganti,cari);
}

void tampil_list()
{
 struct simpul *baca;
 int i;

 baca=awal;
 i=1;

 while(baca!=NULL)
 {

  cout<<"\nNama : "<<baca->nama;
  cout<<"\nUmur : "<<baca->umur;
  cout<<"\n";
  i++;
  baca=baca->berikut;
 }
}

void hapus_list()
{
 struct simpul *hapus;

 hapus=awal;
 while(hapus!=NULL)
 {
  awal=hapus->berikut;
  free(hapus);
  hapus=awal;
 }
}

Contoh program single linked list non circular untuk menghapus semua list ataupun salah satu dengan menggunakan menu:
#include <constream.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

struct nasabah
{
 char norek[12];
 char nama[25];
 char alamat[50];
 double saldo;
};

struct simpul
{
 char norek[12];
 char nama[25];
 char alamat[50];
 double saldo;
 struct simpul *berikut;
};

struct simpul *awal=NULL, *akhir=NULL;
struct nasabah bank;

void tambah_list_dibelakang(struct nasabah info);
void isi_list();
void sisip_list(struct simpul *first,struct nasabah info,char posisi[20]);
void sisip_isi_list();
void tampil_list();
void hapus_simpul(char info);
void hapus_data();
void hapus_list();
void menu();

void main()
{
 clrscr();
 menu();
 getch();
}
void menu()
{
 int pil;
 clrscr();
 cout<<"Programmer : Shandy Johan_6311171"<<endl<<endl;
 cout<<"Pilih Transaksi  : "<<endl;
 cout<<"            1. Isi List"<<endl;
 cout<<"            2. Sisip List"<<endl;
 cout<<"            3. Tampil List"<<endl;
 cout<<"            4. Hapus Salah Satu"<<endl;
 cout<<"            5. Hapus Semua List"<<endl;
 cout<<"            6. Exit"<<endl<<endl;
 cout<<"Tentukan Pilihan : ";
 cin>>pil;
 switch (pil)
 {
  case 1:
       isi_list();
       break;
  case 2:
       sisip_isi_list();
       break;
  case 3:
       tampil_list();
       break;
  case 4:
       hapus_data();
       break;
  case 5:
       hapus_list();
       break;
  case 6:
       clrscr();
       gotoxy(21,13);cout<<"Terima Kasih Telah Menggunakan Program Ini";
       break;
 }
}

void isi_list()
{
 char jawab;

 do
 {
  clrscr();
  cout<<"No Rekening : ";
  cin>>bank.norek;
  cout<<"Nama        : ";
  cin>>bank.nama;
  cout<<"Alamat      : ";
  cin>>bank.alamat;
  cout<<"Saldo Awal  : ";
  cin>>bank.saldo;
  tambah_list_dibelakang(bank);
  cout<<"\n\nTambah Data [Y/T] : ";
  cin>>jawab;
 }
 while (toupper(jawab)!='T');
 menu();
}

void tambah_list_dibelakang(struct nasabah info)
{
 struct simpul *baru;

 baru = (struct simpul *) malloc (sizeof(struct simpul));
 strcpy (baru -> norek,info.norek);
 strcpy (baru -> nama,info.nama);
 strcpy (baru -> alamat,info.alamat);
 baru -> saldo = info.saldo;

 if (awal == NULL)
 {
  awal = baru;
 }
  else
  {
   akhir -> berikut = baru;
  }
 akhir = baru;
 akhir -> berikut = NULL;
}

void tampil_list()
{
 clrscr();
 struct simpul *baca;
 int i;

 baca = awal;
 i = 1;

 while (baca != NULL)
 {
  cout<<"Data Ke : "<<i<<endl;
  cout<<"No Rekening  : "<<baca -> norek<<endl;
  cout<<"Nama         : "<<baca -> nama<<endl;
  cout<<"Alamat       : "<<baca -> alamat<<endl;
  cout<<"Saldo Awal   : "<<baca -> saldo<<endl;
  cout<<endl;
  i++;
  baca = baca -> berikut;
 }
 getch();
 menu();
}

void hapus_list()
{
 struct simpul *hapus;
 hapus = awal;
 while (hapus != NULL)
 {
  awal = hapus -> berikut;
  free(hapus);
  hapus = awal;
 }
 menu();
}


void sisip_list(struct simpul *first, struct nasabah info, char posisi[20])
{
 struct simpul *bantu,*baru;

 baru = new simpul;
 strcpy (baru -> norek,info.norek);
 strcpy (baru -> nama,info.nama);
 strcpy (baru -> alamat,info.alamat);
 baru-> saldo = info.saldo;
 bantu = first;

 do
 {
  if (strcmp(posisi,bantu->norek)!=0)
  {
   bantu = bantu->berikut;
  }
 }
 while (bantu !=NULL & strcmp(posisi,bantu->norek)!=0);

 baru->berikut = bantu -> berikut;
 bantu -> berikut = baru;
}

void sisip_isi_list()
{
 char cari[20];
 struct nasabah ganti;
  clrscr();
  cout<<"Input Data Baru"<<endl;
  cout<<"No Rekening : ";
  cin>>ganti.norek;
  cout<<"Nama        : ";
  cin>>ganti.nama;
  cout<<"Alamat      : ";
  cin>>ganti.alamat;
  cout<<"Saldo Awal  : ";
  cin>>ganti.saldo;
  cout<<endl;
  cout<<"Data Akan Disisipkan Setelah No Rekening : ";
  gets(cari);
  sisip_list(awal,ganti,cari);
  menu();
}

void hapus_simpul(char info[20])
{
 struct simpul *bantu,*hapus;

 if (awal==NULL) { cout<<"\n Data List Kosong ";}
 else
 {
  if (strcmp(awal->norek,info)==0)
  {
   hapus=awal;
   awal=hapus->berikut;
   free(hapus);
  }
   else
   {
    bantu=awal;
    while ((strcmp(info,bantu->berikut->norek)!=0) && (bantu->berikut!=NULL))
    {
     bantu=bantu->berikut;
    }
    hapus=bantu->berikut;
    if (hapus!=NULL)
    {
     if (hapus!=akhir) { bantu->berikut=hapus->berikut;}
     else
     {
      akhir=bantu;
      akhir->berikut=NULL;
     }
     free(hapus);
    }
   }
  }
}


void hapus_data()
{
 char cari[20];
 char jawab;

 clrscr();

 cout<<"\nAda data yang akan dihapus Y/T :";cin>>jawab;
 if (toupper(jawab)=='Y')
 {
  cout<<"\nNo.Rekening yang akan dihapus :";
  gets(cari);
  hapus_simpul(cari);
  menu();
 }
}