Docstoc

MODUL STRUKTUR data 2

Document Sample
MODUL STRUKTUR data 2 Powered By Docstoc
					     MODUL BELAJAR
     STRUKTUR DATA




         Disusun Oleh:

      NURUL HIKMAH, S.Kom




STMIK EL RAHMA YOGYAKARTA

            2010
                                                SILABUS

Pertemuan Pertama                   : PENDAHULUAN DAN KILAS BALIK
Pertemuan Kedua                     : REKURSI
Pertemuan Ketiga                    : TUMPUKAN (STACK)
Pertemuan Keempat                   : POINTER
Pertemuan Kelima                    : SENARAI BERANTAI (LINKED LIST)
Pertemuan Keenam                    : ANTRIAN (QUEUE)
Pertemuan Ketujuh                   : SENARAI BERANTAI BANYAK
Pertemuan Kedelapan                 : POHON (TREE)
Pertemuan Kesembilan                : PENGURUTAN (SORTING)
Pertemuan Kesepuluh                 : PENCARIAN (SEARCHING)

Prosentase Penilaian:
Tugas          : 25.............%
Uts            : 35.............%
Uas            : 40.............%
Jumlah kehadiran:
Presensi       :75%
                                         PENDAHULUAN

Bahasa Pemrograman

Bahasa adalah suatu sistem untuk berkomunikasi. Bahasa tertulis menggunakan simbol (yaitu huruf)
untuk membentuk kata. Dalam ilmu komputer, bahasa manusia disebut bahasa alamiah (natural
languages),dimana komputer tidak bisa memahaminya, sehingga diperlukan suatu bahasa
komputer.

Generasi bahasa pemrograman:

      Generasi I: machine language

      Generasi II: assembly language : Assembler

      Generasi III: high-level programming language: C, PASCAL, dsb.

      Generasi IV: 4 GL (fourth-generation language): SQL

Definisi Program/Pemrograman

      Adalah kumpulan instruksi-instruksi tersendiri yang biasanya disebut source code yang
       dibuat oleh programmer(pembuat program).

      Adalah urutan perintah yang disusun sedemikian rupa, sehingga komputer dapat
       melaksanakan perintah sesuai dengan keinginan pemakai. \

Langkah-langkah Dalam Pemrograman Komputer

      Mendefinisikan masalah (hukum Murphy oleh Henry Ledgard)

      Menemukan solusi

      Memilih algoritma

      Menulis program

      Menguji program

      Menulis dokumentasi

      Merawat program

Pengenalan Struktur Data

Struktur data adalah sebuah skema organisasi, seperti struktur dan array, yang diterapkan pada data
sehingga data dapat diinterprestasikan dan sehingga operasi-operasi spesifik dapat dilaksanakan
pada data tersebut (http://lecturer.eepis-its.edu/entin)

Pengenalan Algoritma
Algoritma adalah barisan langkah-langkah perhitungan dasar yang mengubah masukan (dari
beberapa fungsi matematika) menjadi keluaran. Menurut Dr. Naveen dari intstitut teknologi di india
algoritma adalah sebuah garis besar, esensi dari prosedur komputasi atau bisa juga instruksi
pengerjaan langkah perlangkah.
Contoh :
��Perkalian
Input : integer positif a, b
Output : a X b
Algoritma perkalian :
Contoh kasus : a = 365, b = 24
Metode 1 : 365 * 24 = 365 + (365 * 23)
                 = 730 + (365 * 22)
                 …..
                 = 8760 + (365 * 0)
                 = 8760

Metode 2 :
365
 24
____ x
1460
730
____ +
8760

Manakah algoritma yang lebih baik ?
Kita dapat menyebut algoritma lebih baik dari algoritma yang lain (karena untuk sebuah
kasus bisa lebih dari satu algoritma yang benar) jika:
    1. Efisien waktu pengerjaan dan penggunaan space yang dibutuhkan
    2. Efisiensi sebagai fungsi dari ukuran inputan

Struktur data adalah : pengelompokkan data yang dibutuhkan untuk dapat memecahkan
masalah.
 (sumber: internet)
Ayo kita sedikit bersenang-senang. Berikut ini ada permasalahan dan bagaimana pemecahannya
yang efisien:
    1. Faktorial. Dtulis dengan simbol (n!). penyelesaian secara matematis adalah
        N! = n*(n-1)*(n-2)*... (1) sehingga jika ada 5! = 5*4*3*2*1 = 120.
                              REKURSI (RECURSION)
APA SIH REKURSI?
Salah satu keistimewaan yang dimiliki oleh pascal adalah pascal bisa melakukan proses yang kita
kenal dengan nama rekursi (recursion). Secara harfiah rekursi berarti memanggil dirinya sendiri.
Dalam bahasa pascal hai ini kita implementasikan dengan prosedur atau fungsi. Dalam artian suatu
proses disebut rekursi saat prosedur atau fungsi dipanggil oleh prosedur atau fungsi itu sendiri.
Contoh sederhana untuk menunjukkan proses rekursi adalah untuk menyelesaikan permasalahan
faktorial.
Mari kita telaah lebih dalam mengenai faktorial. Dalam faktorial jika nilai faktorial berupa 0 atau 1
maka hasilnya adalah 1 dan dalam proses rekursi artinya tidak ada pemanggilan diri. Namun jika nilai
faktorial lebih dari 1 maka rekursi akan unjuk gigi.




program re_faktorial;
uses crt;
var x:integer;
function fact (n:integer):integer;
begin
        if n<2 then {syarat operasi berhenti}
        fact:=1
        else
        fact:=n*fact(n-1);{ni dia rekursi}
end;
begin
clrscr;
write('Masukkan sebuah bilangan faktorial:');readln(x);
write(x,'! adalah ',fact(x));
readln();
end.


Tugas :
   1. Buatlah program untuk menghitung faktorial tanpa rekursi. Masukkan angka yang cukup
        besar.
   2. Buatlah program deret fibonacci dengan cara rekursi

REKUSI VS ITERASI

Dalam beberapa kasus rekursi bisa jadi kurang efisien dibandingkan proses iterasi. Iterasi adalah
penyelesaian masalah dengan menggunakan perulangan. Contoh kasus deret fibonacci. Kita telah
membuatnya dalam bentuk rekursi. Namun jika dicermati terdapat banyak ketidak-efisienan. Dalam
kasus deret fibonaccy dengan menggunakan rekursi ada pemanggilan yang berulang untuk suatu
proses yang sebenarnya sudah dikerjakan.
(http://elearning.gunadarma.ac.id)
 Dari gambar diatas terlihat bagaimana kejelekan dari rekursi jika diterapkan pada kasus fibonaccy.
Sekarang mari kita lihat penyelesaian kasus ini dengan proses iterasi.

program fibonaccy;
uses crt;
var x:integer;
function fibo_iterasi(N:integer):integer;
var F, akhir, bantu, I:integer;
begin
        I:=1; F:=1; akhir:=0;
        if N=0 then f:=0;
        while I<>N do
        begin
                bantu:=F;
                I:=I+1;
                F:= F+akhir;
                akhir:=bantu;
                write(akhir,' ');
        end;
        fibo_iterasi:=F;

end;

begin
          clrscr;
          write('masukkan berapa deret fibonacci =');readln(x);
         write(fibo_iterasi(x));
          readln;
end.


Program fibonacci2;
uses crt;
var x:array[1..50] of integer;
i,n:integer;
begin
x[1]:=1;
x[2]:=1;
write('masukkan berapa jml deret: ');readln(n);
write(x[1],' ');
write(x[2],' ');
for i:=3 to n do
begin
x[i]:=x[i-1]+x[i-2];
write(x[i],' ');
end;
writeln;
readln;

end.

THE TOWER OF HANOI

Satu kasus yang dapat diimplementasikan dengan rekursi adalah legenda menara hanoi. Karena
permainan ini dimainkan pertama kali oleh seorang pendeta buddha di hanoi. Proses permainan ini
adalah memindahkan sejumlah piringan dari tonggak pertama(A) ke toggak tujuan(C) dan diijinkan
melewati tonggak bantu(B). Piringan memiliki ukuran yang berbeda. Aturan pemindahannya adalah
piringan dipindahkan satu persatu dan piringan yang lebih besar tidak boleh menindih piringan yang
lebih kecil. Secara umum untuk menyelesaikan n buah piringan akan memakai langkah sejumlah 2 n-1
kali.

Untuk menyelesaikan kasus diatas mari kita membuat sebuah notasi baru yaitu:

                                    TOWER(N, Asal, Bantu, Tujuan)

Notasi diatas bisa kita baca sebagai berikut ini:

Pindahkan N buah piringan dari tonggak asal ke Tonggak tujuan dengan menggunakan Tonggak
bantu

Sekarang mari kita coba selesaikan memindahkan 3 buah piringan. Secara matematis kita akan
memerlukan 7 kali pemindahan:

(Plate terkecil diberi nomor 1, berikutnya 2 dan seterusnya)

langkah ke 1: pindah plate nomor 1 dari tonggak A ke tonggak C(A -> C)

langkah ke 2: pindah plate nomor 2 dari tonggak A ke tonggak B(A -> B)

langkah ke 3: pindah plate nomor 1 dari tonggak C ke tonggak B(C -> B)

langkah ke 4: pindah plate nomor 3 dari tonggak A ke tonggak C(A -> C)

langkah ke 5: pindah plate nomor 1 dari tonggak B ke tonggak A(B -> A)

langkah ke 6: pindah plate nomor 2 dari tonggak B ke tonggak C(B -> C)

langkah ke 7: pindah plate nomor 1 dari tonggak A ke tonggak C(A -> C)

plate sebanyak ; 3 buah perlukan 7 kali pemindahan
program tower_hanoi;
uses crt;
const max=10;
var gerakan, plate :integer;
procedure hanoi(var c_gerak:integer; cacah: integer; A,B,C:char);
begin
        if cacah>0 then
        begin
                 hanoi(c_gerak, cacah-1, A,C,B);
                 c_gerak:=succ(c_gerak);
                 write('langkah ke ',c_gerak:3);
                 write(': pindah plate nomor ',cacah:2);
                 write(' dari tonggak ', A);
                 write(' ke tonggak ', C);
                 writeln('(', A,' -> ', C, ')');
                 hanoi(c_gerak, cacah-1, B,A,C);
        end;
end;
begin
        clrscr;
        gerakan:=0;
        writeln('PENYELESAIAN THE TOWER OF HANOI');
        write('(Plate terkecil diberi nomor 1, ');
        writeln(' berikutnya 2 dan seterusnya)');
        {isi piringan};
        GotoXY(1,5);write('banyaknya plate (max',max:2, '):');
        writeln;
        repeat
                 GotoXY(30,5); write(' , ');
                 GotoXY(30,5); readln(plate);
        until plate <=max;
        hanoi(gerakan, plate, 'A','B','C');
        write('plate sebanyak ; ',plate:2,' buah');
        write(' perlukan ',gerakan:2,' kali pemindahan');
        readln;
end.


Tugas:

   1. Buatlah program untuk menyusun permutasi sekumpulan karakter dengan menggunakan
      rekursi. Jika ada 3 karakter (A,B,C) maka permutasinya adalah 3!
      ABC, BAC,CAB,ACB,BCA dan CBA.
   2. Buat laporan mengenai kelebihan dan kekurangan rekursi dan iterasi.
                                 TUMPUKAN (STACK)
Salah satu konsep yang sangat berguna dalam ilmu komputer adalah sebentuk struktur data yang
disebut dengan stack. Stack atau juga tumpukan adalah kumpulan data yang dimanipulasikan lewat
satu jalan saja. Sehingga untuk menyisipkan dan menghapus lewat satu jalan yang sama yang
disebut sebagai ujug atas tumpukan. Cara ini biasa disebut dengan LIFO (last In first Out) yang
terakhir masuk adalah yang pertama keluar.




              G                         Bisa kita lihat bahwa yang menjadi
                                        elemen pertama adalah A kotak
               F                        merah namun yang akan keluar
               E                        terlebih dahulu adah G ungu yang
                                        merupakan elemen terakhir.
               D

               C

               B

               A


Dalam stack kita hanya bisa menambah dan menghapus dari satu arah saja yaitu ujung bagian atas.
Karenanya ia termasuk dalam kategori kumpulan data yang bersifat dinamis. Lalu bagian manakah
yang disebut sebagai atas tumpukan? Dalam gambar diatas kita akan mengasumsikan bahwa elemen
G adalah atas dari tumpukan. Namun harus di mengerti bahwa penggambaran tumpukan tak selalu
seperti itu. Syarat dikatakan sebagai stack adalah jika ia memanipilasi data dari satu ujung saja.

BAGAIMANA MENYAJIKAN STACK?

Pertanyaan selanjutnya adalah bagaimana mengimplementasikan teknik manipulasi data dengan
stack ini? Dalam bahasa pascal ada beberapa cara untuk dapat menyajikan stack. Cara paling
sederhana yang sudah kita kenal adalah dengan menggunakan larik (array). Jadi mari kita coba
gunakan array dalam stack. Berikut ini adalah contoh deklarasi konstanta, tipe dan variabel yang
akan dipakai dalam penjelasan operasi-operasi stack dengan array.

const max=10;
type
        tipedata :byte;
        stack:array[1..max] of tipedata;
var top: tipedata;

Operasi-operasi pada Single Stack dengan Array
    Create ; membuat sebuah stack baru yang masih kosong. konsepnya adalah bahwa top
       adalah ujung atas stack. Jika top=0 maka stack masih kosong.
                Procedure create;
                Begin
                        Top:=0
                End;
      Full : adalah fungsi untuk memeriksa apakah stack yang ada sudah penuh
       Function full:boolean;
       Begin
                Full:=false;
                If top=max then full:=true;
       End;

      Push : menambahkan sebuah elemen kedalam stack. Hal ini tidak bisa dilakukan jika stack
       sudah penuh.
       Procedure push(elemen:tipedata);
       Begin
               If not full then
               Begin
                     Top:=top+1 {atau bisa ditulis inc(top);}
                     Stack[top]:=elemen;
               End;
       End;

      Pop : mengambil elemen teratas dari stack. Syaratnya stack tidak boleh kosong.
       Procedure pop(elemen:tipedata);
       Begin
              If not empty then
              Begin
                    Elemen:=stack[top];
                    Top:=top-1; {atau dec(top);}
              End;
       End;

      Clear : mengosongkan stack. Jika top=0 maka stack dianggap kosong.
       Procedure clear;
       Begin
                Top:=0
       End;

Untuk lebih jelasnya silahkan coba contoh program dibawah ini dan pahami kinerjanya:
program stack_array;
uses crt;
const max=10;
var
           top,i:byte;
           pil,temp,e:char;
           stack:array[1..max] of char;
procedure PushAnimasi;                {animasi isi stack}
begin
           for i:=1 to 18 do
           begin
                       GotoXY(23+i,7);
                       write(temp);
                       delay(30);
                       GotoXY(23,7);
                clreol;
        end;
        for i:=1 to 14-top do
        begin
                delay(30);
                GotoXY(41,6+i);
                write(' ');
                GotoXY(41,7+i);
                write(temp);
        end;
end;
procedure PopAnimasi(temp:char);
begin                                  {animasi keluarin isi stack}
        for i:=1 to 14-top do
        begin
                 delay(30);
                 GotoXY(41,22-i-top);
                 write(' ');
                 GotoXY(41,21-i-top);
                 write(temp);
        end;
        for i:=1 to 19 do
        begin
                 GotoXY(40+i,7);
                 write(temp);
                 delay(30);
                 GotoXY(16,7);clreol;
        end;
end;
procedure Push(e:char);       {ngisi stack}
begin
        Inc(top);{top:=top+1}
        stack[top]:=e;
        PushAnimasi;
end;
procedure Pop(e:char);
begin
        if top <> 0 then
        begin
                 e:=stack[top];
                 PopAnimasi(e);
                 dec(top);{top:=top-1}
        end else
        begin
                 GotoXY(1,7);
                 write('Stack Sudah kosong');
                 readkey;
                 GotoXY(1,7);clreol;
        end;
end;
begin {program utama}
        clrscr;
        writeln('Pergerakan Stack');
        writeln('1. Push');
        writeln('2. Pop');
        writeln('3. Exit');
        writeln('Pilihan :[1/2/3] ?');
        GotoXY(59,6); write('\');
          GotoXY(59,8); write('/');
          GotoXY(37,10); write('\       /');
          for i:=1 to 11 do
          begin
                  GotoXY(38,10+i);
                  if i=11 then write('|_____|') else write('|                         |');
          end;
top:=0;
repeat
        GotoXY(19,5);
        clreol;
        pil:=readkey;
        write(pil);
        if pil='1' then
        begin
                 if top <> max then
                 begin
                         GotoXY(1,7);
                         write('Masukkan Satu Huruf = ');
                         temp:=readkey;
                         write(temp);
                         Push(temp);
                         GotoXY(1,7); clreol;
                 end else
                 begin
                         GotoXY(1,7);
                         write('Stack Telah Penuh');
                         readkey;
                         GotoXY(1,7); clreol;
                 end;
        end else
        if pil='2' then Pop(temp);
until pil='3';
end.



 Dari contoh diatas, segera kita ketahui bahwa penyajian stack dengan larik kurang tepat karena
banyaknya elemen dalam larik sudah ditetapkan sedangkan dalam stack, banyaknya elemen bisa
sangat bervariasi (dinamis). Meskipun demikian array dapat kita gunakan dengan asumsi banyaknya
elemen stack tidak akan melebihi batas maksimum elemen dalam larik. Hingga suatu saat ukuran
tumpukan akan sama dengan ukuran larik, jika kita teruskan menambah data lagi maka akan terjadi
overflow. Dengan demikian perlu data tambahan untuk mencatat posisi ujung tumpukan. Dengan
kebutuhan seperti ini maka kita bisa menyajikan stack menggunakan tipe data terstruktur yang lain
yaitu: record (rekaman).

Penyajian Stack dengan Record

Untuk memenuhi kebutuhan mencatat posisi ujung tumpukan agar kita tidak kehilangan jejak maka
kita akan menggunakan record yang terdiri dari dua medan. Medan pertama bertipe larik untuk
menyimpan rekaman dan medan kedua bertipe integer untuk mencatat posisi ujung tumpukan.
Dengan anggapan seperti itu maka kita dapat mendeklarasikan tumpukan seperti berikut ini:
Const Max=255;

Type tumpukan = record

                        Isi : array[1..Max] of integer;

                        Atas : 0..Max

                End;

Var T:tumpukan;

Dengan deklarasi diatas kita menganggap bahwa elemen tumpukan T, yang tersimpan dalam larik
T.isi, adalah bertipe integer, dan banyaknya elemen tumpukan maksimum adalah 255. Elemen
tumpukan tak harus bertipe integer. Seperti contoh program stack dengan array kita menggunakan
char. Tetapi tipe data dari Atas (yang menunjukkan ujung tumpukan) harus bernilai bilangan bulat
antara 0 sampai Max yang ditentukan. Contoh jika T.Atas bernilai 5 berarti dalam tumpukan ada 5
elemen. Jika tumpukan dikurangi maka T.Atas adalah T.Atas-1 (4) dan jika tumpukan di tambah
berarti T.Atas adalah T.Atas+1 (5).

Operasi Push dan Pop

Berikut adalah operasi dasar untuk mem-push tumpukan:
procedure Push (var T:tumpukan; x:char);
begin
      if T.atas = max then
            writeln(‘tumpukan sudahh penuh’)
      else
      begin
        T.atas:=T.atas+1;
        T.isi[T.atas]:=x; {masukan huruf}
      End;
end;


Berikut ini adalah operasi dasar mem-pop tumpukan:
function Pop (var T:tumpukan):char;
begin
if T.atas = 0 then
      writeln(‘tumpukan kosong’)
else
      begin
        Pop:=T.isi[T.atas];
        T.atas:=T.atas-1;
      End;
end;


Silakan pelajari contoh program berikut ini:
program balik_kata;
uses crt;
const elemen=225; {batas max karakter}
type s225=string[elemen];
tumpukan = record
                isi : s225;
                atas : 0..elemen
                 end;
var T:tumpukan; {nama tumpukan}
I:integer;      {pencacah}
kalimat:s225;   {kalimat yang akan dibalik}
procedure create (var T:tumpukan);
begin
        T.Atas:=0; {inisialisasi / create tumpukan}
end;
procedure Push (var T:tumpukan; x:char);
begin
        T.atas:=T.atas+1;
        T.isi[T.atas]:=x; {masukan huruf}
end;
function Pop (var T:tumpukan):char;
begin
        Pop:=T.isi[T.atas];
        T.atas:=T.atas-1;
end;
{program Utama}
begin
        clrscr;
        create(T);
        writeln('Stack untuk membalik kalimat');
        writeln('----------------------------');
        writeln;
        write('ketikkan kalimatmu : '); readln(kalimat);
        clrscr;
        writeln('Kalimat Aslinya : ', kalimat);
        writeln;
        writeln('Dibalik menjadi :');
        for I:=1 to length(kalimat) do
                 Push (T, kalimat[I]); {memasukkan kalimat ke stack};
        for I:=1 to length(kalimat) do
                 write(Pop(T));
        readln;
end.



Tugas :

   1. Buatlah program yang menampilkan pergerakan karakter masuk ke wadah dan keluar
      hingga terbaca terbalik
                           TIPE DATA POINTER

Pertama mari kita kenali array dengan baik dan perbedaannya dengan pointer. Pankaj
Shukla dari indian institut of technology menjelaskan:
Kebutuhan Array:
1. Data harus diletakkan dalam sebuah variabel.
2. Kebututuhan memori suatu variabel tertentu yang tergantung pada milik siapa type
    tersebut. Artinya :kebutuhan memori berbagai variabel yang dideklarasikan akan
    memakan byte memori yang berbeda-beda. Misal kita ingin menyimpan ratusan data
    salam sebuah program. Kita berikan mereka nama variabel yang berbeda-beda, yakinlah
    mengingat-ingat mereka semua sangat membosankan/menyebalkan.
3. Maka akan lebih mudah untuk kita jika kita bisa memberi mereka nama yang sama
    sebagai nama induk yang akan mengacu pada semua nilai yang ada.
4. Nilai tertentu disebutkan menggunakan indeks, yang menunjukkan yang mana nilai
    pertama, kedua atau keseratus.

Jadi kita bisa menyimpulkan bahwa array adalah pengkoleksian dari lokasi memori yang
berurutan (sequensial). Yang mana saat deklarasi kita butuh menyebutkan nama array,
tipenya dan panjangnya. Misal kita butuh 100 array yang bertipe integer. Maka kita akan
mendeklarasikannya sebagai berikut:

                      Var nim:array[1..100] of integer;
Nim adalah nama array, tipenya adalah integer dan rangenya adalah 1 sampai 100. Ketika
kita katakan nim[5] artinya kita menyebutkan isi data ke 5 dari nim. Yang harus diketahui
pasti adalah ukuran dari array adalah selalu konstan. Ini karena besarnya jumlah memori
akan dilaokasikan sebelum program dijalankan. Metode ini dikenal sebagai “static
allocation”. Karena itulah pemakaian larik bisa dikatakan kurang tepat.

Telah kita ketahui pemakaian larik tidak selalu tepat. Terutama karena batasan data yang
dapat dimasukkan. Penambahan record hanya memecahkan satu masalah saja. Namun
masalah utamanya yaitu letak kedinamisannya. Karenanya dibutuhkan satu tipe data yang
digunakan untuk mengalokasikan dan mendealokasikan pengingat secara dinamis, yaitu
sesuai kebutuhan pada saat program di eksekusi. Tipe data tersebut kita kenal dengan nama
pointer (penunjuk). Mari kita mengenali dengan baik mengenai pointer.
Sebenarnya saat kita mendeklarasikan sebuah variabel kita sedang mengalokasikan memori
untuk berbagai tujuan. Saat ia berupa alokasi statis, dipakai atau tidak, mamori tersebut
sudah terlanjur di”pesan”. Prisip ini berbeda dengan pointer.
1. Memori komputer sebenarnya adalah kumpulan sel penyimpanan. Lokasi-lokasi ini
    diberi nomor secara berurutan dan disebut addresses.
2. Pointer adalah addresses dari lokasi memori. Berbagai variabel, yang berisi sebuah
    alamat adalah variabel pointer.
3. Variabel pointer menempatkan alamat tersebut untuk sebuah objek. Bisa untuk
    manipulasi tak langsung terhadap objek tersebut.
4. Pointer dideklarasikan denggunakan tanda “caret” atau “circumflex” (^).
    Type
    Catatanmahasiswa=record
                        Nim:string[10];
                        Nama:string[30];
                        Prodi:string[15];
                            End;
           Penunjukmahasiswa=^catatanmahasiswa;
           Var Datamahasiswa=Penunjukmahasiswa;

       5. Pointer datamahasiswa adalah variable pointer yang menunjuk pada letak record
          catatanmahasiswa.

       Sebelum kita maencoba pointer mari kita ketahui terlebih dahulu mengenai pengalamatan
       pointer dalam komputer.

       HEAP

       Heap adalah memori-memori di komputer yang belum dialokasikan, yaitu memori yang tidak
       digunakan oleh DOS (oleh program-program yang under DOS termasuk pascal). Heap ini
       akan menempati sebagian atau seluruh sisa memori yang belum digunakan sewaktu
       program dijalankan.

       Penggambaran mengenai heap ini seperti stack

              Memori yang masih               freePtr
                  tersisa

           Heap akan naik ke high             heapPtr
                  memori

           Memori yang ditempati              HeapOrg
           oleh data pascal (data
                 segmen)
                                              Dseg
          Memori yang digunakan
           oleh program turbo
          pascal (code segment)
                                               Cseg
          Memori untuk program
                 resident
                   DOS




                  Bawah




Menyajikan Pointer

Sebelumnya kita telah mengetahui bagaimana cara mendeklarasikan sebuah pointer. Sekarang mari
kita telusuri lebih lanjut. Berikut ada program pointer sederhana;
program pointer1;
uses crt;
type TString = String[15];
        Pstring = ^TString;
        var matkul : Pstring;
begin
clrscr;
          new(matkul);
          matkul^:='Struktur Data';
          writeln(matkul^);
          writeln;
          readln;
end.


Pertanyaannya adalah apa yang akan ditampilkan program diatas? Ya yang ditampilkan adalah value
yaitu struktur data tetapi pengambilan nilai tersebut tidak secara langsung. Melainkan melalui
sebuah alamat.

OPERASI-OPERASI PADA POINTER

   1. PROSEDUR NEW
      Pointer dialokasikan pertama kali dengan prosedur standar new. Dengan prosedur ini maka
      variabel dinamik akan ditempatkan di heap dan posisi dari variabel dinamik ini di heap akan
      ditunjukkan oleh variabel pointer.
      Perhatikan contoh program berikut ini:
program pointer2;
uses crt;
type Pmahasiswa=^notemahasiswa;
notemahasiswa=record
                 nim:string[10];
                 nama:string[30];
                 prodi:string[20];
                 end;
var dm1,dm2,dm3:Pmahasiswa;
begin
        clrscr;
        GotoXY(15,1);writeln('INPUT DATA MAHASISWA');
        GotoXY(15,2);writeln('====================');
        writeln;
        writeln('Mahasiswa ke 1');
        new(dm1);
        with dm1^ do
        begin
               write('Nomor Induk Mahasiswa : ');readln(nim);
               write('Nama Mahasiswa : ');readln(nama);
               write('Program Studi : ');readln(prodi);
        end;
        writeln;
        writeln('Mahasiswa ke 2');
        new(dm2);
        with dm2^ do
        begin
               write('Nomor Induk Mahasiswa : ');readln(nim);
               write('Nama Mahasiswa : ');readln(nama);
               write('Program Studi : ');readln(prodi);
        end;
        writeln;
        writeln('Mahasiswa ke 3');
        new(dm3);
        with dm3^ do
        begin
               write('Nomor Induk Mahasiswa : ');readln(nim);
                    write('Nama Mahasiswa : ');readln(nama);
                    write('Program Studi : ');readln(prodi);
          end;
          writeln;
          clrscr;
          writeln('Data Mahasiswa Diambil Dari Memori');
          writeln('==================================');
          writeln;

writeln('==============================================================
======');
        writeln('| NIM        | NAMA MHS                      | PROGRAM
STUDI       |');

writeln('==============================================================
======');
        with dm1^ do writeln('| ',nim:10,' |',nama:30,' |',prodi:20,'
|');
        with dm2^ do writeln('| ',nim:10,' |',nama:30,' |',prodi:20,'
|');
        with dm3^ do writeln('| ',nim:10,' |',nama:30,' |',prodi:20,'
|');

          readln;
end.

       Jika ada 3 variabel dinamik maka ada penggunaan prosedur new sebanyak itu juga.
       Berikut penggambaran penempatan data di heap:
                       (High memory)
       heapPtr
                      DM1
                      DM2
                      DM3
                      (Low memory)


       Prosedur new hanya mengalokasi atau membuat suatu variabel dinamik dalam heap. Sedang
       nilai datanya masih kosong. Untuk mengisikan datanya dapat dilakukan seperti pada variabel
       statis biasa yaitu:

       Dm1^.nim:=’11090234’;
       Dm1^.nama:=’Addaffa’;
       Dm1^.prodi:=’Sistem Informasi’;

       Atau kita bisa memanfaatka statement with .. do seperti berikut ini:


       with dm1^ do
         begin
                 Dm1^.nim:=’11090234’;
                 Dm1^.nama:=’Addaffa’;
                 Dm1^.prodi:=’Sistem Informasi’;

          end;

  2. DISPOSE, MARK DAN RELEASE
Untuk manipulasi lebih lanjut adalah dispose, mark dan release. Ketiganya berkaitan.
Ketiganya bertujuan menghapus variabel dinamik dari heap. Jika suatu variabel dinamik
dihapus dengan prosedur standar dispose maka akan membekas berlubang (hole /
fragmented). Mari kita gambarkan prosedur dispose terhadap 3 variabel dinamik diatas:

               (High memory)

               DM3
               DM2
               DM1
               (Low memory)

Kemudian kita menuliskan perintah berikut ini:
Dispose(Dm2^);

Maka akan variabel dm2 akan terhapus dari heap yang mengakibatkan heap berlubang
seperti dibawah ini.

               (High memory)

               DM3

               DM1
               (Low memory)


Sekarang mari kita gunakan prosedur standar mark dan release. Prosedur mark digunakan
untuk menanda variabel dinamik yang memorinya akan dilepaskan. Dan dilanjutkan dengan
prosedur release yang akan melepaskan memori dalam artian menghapus variabel dinamik.
Mari kita perhatikan penggambarannya:

               (High memory)

               DM4
               DM3
               DM2
               DM1
               (Low memory)


Data awal yang memiliki 3 variabel dinamik. Misalkan codenya seperti dibawah ini:
New(dm1);
New(dm2);
Mark(hapus);
New(dm3);
New(dm4);

Perintah diatas akan menyebabkan ke empat elemen digiring ke heap, namun setelah
elemen kedua akan ditandai (mark) oleh pointer hapus. Selanjutnya dengan statement
berikut:
Release(hapus);
       Maka mulai dari variabel yang letaknya ditunjuk oleh pointer hapus akan dihapuskan dari
       heap. Sehingga didapat data seperti dibawah ini:

                      (High memory)

                      DM2
                      DM1
                      (Low memory)




POINTER DAN LARIK = MAKIN OKE

Penggunaan pointer bukan berarti mengesampingkan kegunaan array. Kita bisa menggabungakan
keduanya. Bayangkan jika kita punya ratusan atau ribuan data yanga harus dimasukkan, apakah kita
akan mendeklarasikannya variabel dinamik ini satu persatu, tentu tidak. Ada 2 solusi untuk
mengatasi masalah ini. Pertama dengan array kedua dengan linked list. Kita akan membahas yang
pertama terlebih dahulu. Sebenarnya larik dinamik bentuknya sama saja dengan larik biasa, hanya
dia dialokasikan ke heap dengan prosedur New. Untuk lebih jelasnya perhatikan contoh dibawah ini:
program pointer2;
uses crt,SysUtils;
type Pmahasiswa=^notemahasiswa;
notemahasiswa=record
                 nim:string[10];
                 nama:string[30];
                 prodi:string[20];
                 end;
var dmahasiswa:array [1..25] of Pmahasiswa;
i,jum:integer;
begin
        clrscr;
        writeln('MEMASUKKAN DATA MAHASISWA');
        writeln;
        write('berapa jumlah mahasiswa : ');readln(jum);
        for i:=1 to jum do
        begin
                 writeln;
                 writeln('Mahasiswa ke ',i:2,':');
                 new(dmahasiswa[i]);
                 with dmahasiswa[i]^ do
                 begin
                         write('Nomor Induk Mahasiswa :');readln(nim);
                         write('Nama Mahasiswa :');readln(nama);
                         write('Program studi :');readln(prodi);
                 end;
        end;
        clrscr;
        writeln('DATA MAHASISWA DIAMBIL DARI HEAP');
        writeln('==================================');
        writeln;

writeln('==============================================================
======');
        writeln('| NIM          | NAMA MHS                    | PROGRAM
STUDI       |');

writeln('==============================================================
======');
        for i:=1 to jum do
        begin
        with dmahasiswa[i]^ do writeln('| ',nim:10,' |',nama:30,'
|',prodi:20,' |');
        end;
        readln;
end.


CONTOH PENGGUNAAN STACK DENGAN POINTER
program stackpointer;

uses crt;

type Pstack = ^isistack;

isistack = record

        data : char;

        prev : Pstack;

        end;

var

        last, current:Pstack;

procedure tambah(i:char);

begin

        new(current);{buat stack baru}

        current^.data:=i;{membuat nilai item ke nilai parameter}

        current^.prev:=last;{mengeset nilai sebelumnya pada pada item
terakhir dalam stack}

        last := current; {membuat item current menjadi item last yang
baru}

end;

procedure lihat;

begin

        current:=last;

        while current <> nil do

        begin

                   writeln(current^.data,' ');
                    current := current^.prev;

          end;

end;

procedure hapus;

begin

          while last <> nil do

          begin

                    current := last^.prev;

                    dispose(last);

                    last:=current;

          end;

end;

begin

clrscr;

          last:=nil;

          tambah('A');

          tambah('B');

          tambah('C');

          lihat;

          hapus;

          readln;

end.




Tugas :

   1. Buatlah algoritma dan program implementasi stack dengan pointer. (data dan thema
      terserah masing-masing kelompok)
                                      LINKED LIST
                                 (Senarai Berantai)
Secara harfiah atau dalam pemakaian sehari-hari istilah list (senarai) diartikan kumpulan linier
sejumlah data. Bisa kita contohkan adalah daftar belanja harian kita. Lihat contoh daftar belanja
dibawah ini:

  Kangkung 2 ikat                       Kangkung 2 ikat

  Tempe 2 papan                         Tempe 2 papan

  Ebi                                   Ebi

  Cabai merah                           Cabai merah

  Bawang merah                          Bawang merah

                                        Bawang putih

                                        Sabun cuci piring


     Gb. Daftar belanja                 Gb. Daftar belanja hari
     hari pertama                       kedua


Seperti halnya daftar belanjaan kita, pengelolaan data di komputer terkadang pun seperti itu. Kita
akan melakukan penyimpanan data atau pengolahan data lainnya yang telah terorrganisir dalam
sebuah urutan tertentu. Cara yang biasa kita lakukan adalah dengan larik. Namun kali ini mari kita
lakukan dengan cara yang berbeda. Perkenalkan linked list.

SINGLE LINKED LIST

Bayangkan jika tiap kali kita butuh menyimpan data kita butuh mendeklarasikan satu buah pointer,
akan ada berapa banyak variabel dinamik dalam program kita? Nah alangkah lebih efisisennya jika
kita cukup membuat satu variabel dinamik yang saling memiliki keterkaitan. Perhatikan gambar
berikut ini:

 P            0119        Aku
              1190        Mahasiswa
              1298        STMIK
              1299        El Rahma
              ...                                      NIL
              FFFF

Tampak sederet data dalam lokasi memori tertentu. Tempat yang disediakan pada suatu area
memori tertentu untuk penyimpanan data dikenal dengan sebutan node/simpul. Pada setiap node
memiliki pointer yang menunjuk ke simpul berikutnya sehingga terbentuk sebuah untaian dan
dengan demikian kita hanya membutuhkan satu variabel dinamik. Simpul yang terakhir akan
menunjuk ke nil (nil tidak memiliki nilai apapun). Inilah yang disebut single linked list.

Aplikasi single linked list dapat menggunakan 2 metode:

      1. LIFO (last in first out) aplikasinya adalah stack (tumpukan).
      2. FIFO (first in first out) aplikasinya adalah Queue (antrian).

Cara Penyajian Linked List

Sebelum kita mempelajari operasi-operasi yang dapat dilakukan pada linked list, kita kenali dulu
bagaimana sebenarnya sebuah linked list disimpan dalam memori utama. Biasanya kita akan
menggambarkan linked list dengan gambaran yang berurutan dan teratur, namun harus diingat
bahwa dalam penyimpanan yang sebenarnya di memori tidak harus atau bahkan tidak seperti itu.
Kita sudah memehami bahwa pointer adalah alamat lokasi tertentu dalam memori. Perhatikan 2
gambaran berikut ini:

  A                B              C             D              E              F




                                Medan sambungan/pointer

  Awal
                       Item informasi/data dari node



Mari kita namakan linked list diatas sebagai DAFTAR. DAFTAR diatas akan disajikan dalam pengingat
dengan cara seperti berikut ini:

                                               INFO          SAMBUNGAN
                                       1         C               5
                                       2         A               6
                                       3
                                       4
      2(AWAL)
                                       5            D                    10
                                       6            B                    1
                                       7
                                       8            F                0/nil                 habis
                                       9
                                      10            E                    8
Dapat kita lihat sebenarnya dalam memori penyimpanan data tidaklah selalu berurutan. Namun
yang terpenting adalah alamat dan sambungan yang membuat mereka lebih teratur. Pertama
DAFTAR mambutuhkan dua buah vektor. Mari kita namakan vektor INFO & SAMBUNGAN. Vektor
info berisi data/nilai yang tersimpan di medan informasi dan vektor sambungan berisi medan pointer
ke node yang berikutnya. Disamping itu DAFTAR juga butuh perubah AWAL yang berisi alamat dari
data informasi pertama dari linked list dan pointer sentinel yang bernama kosong/nil yang
menunjukkan akhir dari pointer.

OPERASI-OPERASI PADA LINKED LIST

   1. Menambah Node
      Dalam operasi menambah node, ada beberapa cara yang bisa kita terapkan. Yaitu :
      menambah di belakang, di depan dan di tengah. Ketiganya memiliki metode yang berbeda-
      beda. Mari kita pelajari dulu deklarasi linked list seperti berikut ini:

       type
         pointer=^DataNilai;
         DataNilai=record
                 nilaihrf : char;
                 next : pointer;
                 end;

       var First,Last,baru: pointer;
                elemen :char;
       1.1. Menambah Di Depan
            Operasi penambahan node ini adalah proses dimana node akan selalu diletakkan di awal
            linked list. Secara garis besar operasi penambahannya bisa dijelaskan sebagai berikut ini:
            a. Pertama pointer pada node yang ditunjuk oleh pointer baru dibuat sama dengan
                yang ditunjuk pointer first. (baru menujuk ke first)
            b. Kedua pointer first akan dibuat sama dengan baru (first menunjuk ke baru)
            c. Kemudian node baru akan diperlakukan sebagai first

               procedure InFront(var first,last :pointer; elemen:char);
                     var baru : pointer;
               begin
                     new(baru);
                     baru^.nilaihrf:= elemen;
                     if first = nil then
                           last := baru
                     else
                           baru^.next:=first;
                     first:=baru;
               end;


       1.2. Menambah Di Belakang
            Operasi ini adalah operasi yang memperlakukan / meletakkan node baru selalu menjadi
            yang terakhir dari untaian. Urutan kerjanya adalah sebagai berikut:
            a. Pointer last adalah pointer yang menunjuk node terakhir dan node yang ditunjuk
               pointer baru adalah node yang akan disambung.
   b. Pointer pada node yang ditunjuk pointer last dibuat menunjuk ke node yang sama
      dengan pointer baru.
   c. Kemudian pointer last dibuat menunjuk ke node yang sama dengan pointer baru.

       procedure InBack(var first,last :pointer; elemen:char);
       var baru : pointer;
       begin
                  new(baru);
                  baru^.nilaihrf:= elemen;
                  if first = nil then
                        first := baru
                  else
                        last^.next:=baru;
                  last:=baru;
                  last^.next:=nil;
       end;

1.3. Menambah Di Tengah
     Untuk menambah node ditengah untaian node. Kita akan membutuhkan pointer lain.
     Misal kita beri nama pointer Bantu. Dalam hal ini node yang akan ditambahkan akan
     diletakkan setelah node yang ditunjuk oleh pointer bantu. Langkah-langkahnya akan
     menjadi seperti berikut ini:
     a. Pertama kita akan menentukan dimana node yang ditunjuk oleh pointer baru akan
         diletakkan dengan menggunakan petunjuk dari pointer bantu.
     b. Pointer pada node yang ditunjuk oleh pointer baru akan menunjuk pada pointer
         pada node yang sama dengan pointer pada node yang ditunjuk oleh pointer bantu.
     c. Selanjutnya pointer pada node yang ditunjuk oleh pointer bantu akan menunjuk
         pointer pada node yang ditunjuk oleh pointer baru.
         Perlu diperhatikan urutan langkah tidak boleh terbalik karena dalam hal ini setiap
         node diurutkan secara alphabetik. Sehingga harus dicari tempat yang sesuai untuk
         nya.

       procedure InCenter(var first,last :pointer; elemen:char);
       var baru,bantu : pointer;
       begin
                  new(baru);
                  baru^.nilaihrf:= elemen;
                  if first = nil then
                  begin
                        first := baru;
                        last := baru;
                  end
                  else
                  {cari lokasi}
                  Begin
                        Bantu:=first;
                        While elemen > baru^.next^.nilaihrf do
                              Bantu:= Bantu^.next;

                               Baru^.next:=bantu^.next;
                               Bantu^.next:=bantu;
                       end;
       end;
2. Menghapus Node
   Operasi berikutnya yang bisa kita lakukan adalah menghapus node. Dalam menghapus node
   kitapun bisa menghapus node yang berada di depan, tengah atau akhir. Metode untuk
   ketiga proses penghapusan ini berbeda-beda. Mari kita pelajari satu persatu:
   2.1. Mengahapus Node Di Depan (pertama)
        Dalam proses pengahapusan kita akan membutuhkan pointer bantu. Pada proses
        menghapus node pertama urutan langkahnya adalah sebagai berikut ini:
        a. Pointer pada node yang ditunjuk pointer first akan ditunjuk juga oleh pointer bantu.
            (bantu dibuat sama dengan first)
        b. Pointer first akan kita pindah ke node yang ditunjuk oleh pointer dari node yang
            tunjuk pointer bantu.
        c. Node yang ditunjuk oleh pointer bantu kita dispose.

   2.2. Menghapus Node Di Tengah Atau Terakhir.
        Untuk menghapus node yang berada ditengah atau akhir kita akan mambutuhkan 2
        pointer bantuan yaitu bantu dan hapus. Urutan langkahnya adalah sebagai berikut ini:
        a. Pertama pointer bantu akan kita letakkan disebelah kiri dari node yang akan
            dihapus. Node yang akan dihapus kita tunjuk dengan pointer hapus.
        b. Pointer pada node yang ditunjuk pointer bantu akan menunjuk pada node yang
            sama yang ditunjuk oleh pointer yang ditunjuk oleh pointer hapus.
        c. Selanjutnya node yang ditunjuk oleh pointer hapus kita dispose.


           procedure DelNodes(var first,last:pointer; elemen:char);
           var bantu,hapus:pointer;
           begin
                 if first = nil then
                 writeln(‘Linked List Kosong’)
                 else
                 if first^.nilaihrf=elemen; {node pertama hapus}
                 begin
                 hapus:=first;
                 first:=hapus^.next;
                 dispose(hapus);
                 end
                 else
                 {menghapus node tengah atau akhir}
                 Begin
                       Bantu:=first;
                       While (elemen <> bantu^.nilaihrf) and
                       (bantu^.next <> nil) do
                             Bantu:=bantu^.next;
                       Hapus:=bantu^.next;
                       If hapus <> nil then
                       Begin
                       If hapus <> last then {node tengah}
                             Bantu^.next:=hapus^.next
                             Else
                             Begin
                                   Last:=bantu;
                                    Lsst^.next:=nil;
                               End;
                         Dispose(hapus);
                         End
                         Else
                         Writeln(‘Node Tidak ditemukan’);

                  End;
          end;

3. Membaca Node
   Setelah kita memiliki data yang cukup banyak pada linked list kita, maka kita bisa
   membacanya dalam 2 cara : dari kanan ke kiri (membaca mundur) atau dari kiri ke kanan
   (membaca maju).
   3.1. Membaca Maju
        Untuk membaca maju uruta langkahnya adalah sebagai berikut:
        a. Pertama pointer bantu akan menunjuk node yang sama dengan pointer first.
        b. Setelah isi nodenya dibaca, maka pointer bantu akan digerakkan menuju ke node
           berikutnya.
        c. Proses ini diulang sampai bantu=last.


          procedure readforward(var first,Last:pointer);
          var bantu:pointer;
          begin
                bantu:=first;
                repeat
                      write(bantu^.nilaihrf:3);
                      bantu:=bantu^.next;
                until bantu = nil;
          writeln;
          end;

   3.2. Membaca Mundur
        Kita juga bisa membaca linked list dengan cara mundur. Dalam proses membaca
        mundur bisa kita lakukan dengan 2 cara. Yaitu dengan perulangan seperti diatas atau
        dengan proses rekursi. Caranya sama hanya pada proses dengan rekursi pencetakan
        ditunggu hingga bantu = last.

          procedure readbackward(var first,Last:pointer);
          var bantu,bantu1:pointer;
          begin
                bantu:=first;
                first:=last;
                repeat
                      bantu1:=bantu;
                      while bantu1^.next <> last do
                      begin
                            write(bantu1^.nilaihrf);
                            bantu1:=bantu1^.next;
                      end;
                      last^.next:=bantu1;
                      last:=bantu1;
                    until last = bantu;
                    last^.next:=nil;
             end;
             procedure backward(bantu:pointer);
             begin
             if bantu <> nil then
                   begin
                         backward(bantu^.next);
                         write(bantu^.nilaihrf);
                   end;
             end;



  4. Mencari Node
     Untuk mencari sebuah node pada dasarnya sama seperti kita hendak menghapus harus
     ditentukan keberadaannya. Dan cara kerjanya sama dengan membaca node tetapi perlu
     ditambah tes untuk menentukan apakah data benar-benar ada.

     Function Datafound(first:pointer; elemen:char):boolean;
     Var ketemu:boolean;
     Begin
           Ketemu:=false;
           Repeat
                If first^.nilaihrf = elemen then
                Ketemu:=true
                Else
                If first^.nilaihrf < elemen then
                First:=first^.next
                Else {data tidak ditemukan}
                Bantu:=nil;
           Until ketemu or (awal=nil);
           Datafound:=ketemu;
     End;


  Untuk lebih memahaminya silakan perhatikan 2 contoh program dibawah ini:

program single_linkedlist;
uses crt;
type
        pointer=^DataNilai;
        DataNilai=record
                nilai : integer;
                next : pointer;
                end;

var list : pointer;
procedure InFront(var L:pointer; X:integer);
var baru : pointer;
begin
        new(baru);
        baru^.nilai:= X;
        baru^.next:=NIL;
        if L=NIL then L:=baru
        else
        begin
                baru^.next:=L;
                L:=baru;
        end;
end;
procedure InCenter(var L:pointer; X,Y:integer);
var baru,bantu:pointer;
begin
        bantu:=L;
        while bantu^.next <> NIL do
        begin
                if bantu^.nilai=X then
                begin
                        new(baru);
                        baru^.nilai:=Y;
                        baru^.next:=bantu^.next;
                        bantu^.next:=baru;
                end;
                bantu:=bantu^.next;
        end;
end;
procedure InBack(var L:pointer; X:integer);
var
baru,bantu:pointer;
begin
        new(baru);
        baru^.nilai:=X;
        baru^.next:=NIL;
        bantu:=L;
        while bantu^.next<>NIL do
                bantu:=bantu^.next;
        bantu^.next:=baru;
end;
procedure DelFront(var L:pointer);
var bantu:pointer;
begin
        bantu:=L;
        if L=NIL then Writeln('List sudah kosong!')
        else
        begin
                L:=L^.next;
                dispose(bantu);
        end;
end;
procedure DelCenter(var L:pointer; X:integer);
var bantu,hapus:pointer;
begin
        bantu:=L;
        new(hapus);
        if bantu = NIL then writeln('List sudah kosong!')
        else
        begin
                bantu:=L;
                new(hapus);
                while bantu^.next <> NIL do
                begin
                if bantu^.next^.nilai=X then
                begin
                        hapus:=bantu^.next;
                        bantu^.next:=hapus^.next;
                        dispose(hapus);
                end
                else
                bantu:=bantu^.next;
                end;
        end;
end;
procedure DelBack(var L:pointer);
var hapus,bantu:pointer;
begin
        bantu:=L;
        if bantu = NIL then writeln('List sudah kosong!')
        else
        begin
                 while bantu^.next^.next <> NIL do
                         bantu:=bantu^.next;
                         new(hapus);
                         hapus:=bantu^.next;
                         bantu^.next:=NIL;
                         dispose(hapus);
        end;
end;
procedure print(var L:pointer);
var bantu:pointer;
begin
        bantu:=L;
        while bantu <> NIL do
        begin
                 write(bantu^.nilai:3);
                 bantu:=bantu^.next;
        end;
end;
var nhrf,nhrf1 : integer;
jwb : char;
begin
        clrscr;
        new(list);
        list:=nil;
        jwb:='Y';
        Writeln('MASUK DARI DEPAN');
        while UpCase(jwb)='Y' do
        begin
                 write('Masukkan Nilai : ');readln(nhrf);
                 Infront(list,nhrf);
                 write('Lagi [Y/N] ? ');readln(jwb);
        end;
        print(list);
        writeln;
        jwb:='Y';
        writeln('MASUK DARI BELAKANG');
        while UpCase(jwb)='Y' do
        begin
                 write('Masukkan Nilai : ');readln(nhrf);
                 InBack(list,nhrf);
                 write('Lagi [Y/N] ? ');readln(jwb);
        end;
        print(list);
        writeln;
        writeln('MASUK DARI TENGAH');
        while UpCase(jwb)='Y' do
        begin
                 write('Masukkan Nilai : ');readln(nhrf);readln(nhrf1);
                 InCenter(list,nhrf,nhrf1);
                 write('Lagi [Y/N] ? ');readln(jwb);
        end;
        print(list);
        writeln;
        writeln('HAPUS DEPAN');
        DelFront(list);
        print(list);
        writeln;
        writeln('HAPUS BELAKANG');
        DelBack(list);
        print(list);
        writeln;
        writeln('HAPUS TENGAH');
        write('Masukkan Huruf yang akan di hapus : '); readln(nhrf);
        DelCenter(list,nhrf);
        print(list);
        writeln;
        readln;
end.

Program kedua :
program single_linked_list2;
uses crt;
type
        pointer=^DataNilai;
        DataNilai=record
                nilaihrf : char;
                next : pointer;
                end;

var First,Last,baru: pointer;
      elemen,pil :char;
procedure InFront(var first,last :pointer; elemen:char);
var baru : pointer;
begin
                 new(baru);
                 baru^.nilaihrf:= elemen;
                 if first = nil then
                        last := baru
                 else
                        baru^.next:=first;
                 first:=baru;
end;
procedure InBack(var first,last :pointer; elemen:char);
      var baru : pointer;
      begin
                 new(baru);
                 baru^.nilaihrf:= elemen;
                 if first = nil then
                        first := baru
                 else
                       last^.next:=baru;
                 last:=baru;
                 last^.next:=nil;
      end;
procedure InCenter(var first,last :pointer; elemen:char);
      var baru,bantu : pointer;
      begin
                 new(baru);
                 baru^.nilaihrf:= elemen;
                 if first = nil then
                 begin
                       first := baru;
                       last := baru;
                 end
                 else
                 {cari lokasi}
                 Begin
                       Bantu:=first;
                       While elemen > baru^.next^.nilaihrf do
                             Bantu:= Bantu^.next;

                        Baru^.next:=bantu^.next;
                        Bantu^.next:=bantu;
                 end;
      end;
procedure DelNodes(var first,last:pointer; elemen:char);
           var bantu,hapus:pointer;
           begin
           if first = nil then
           writeln('Linked List Kosong')
           else
           if first^.nilaihrf=elemen then {node pertama hapus}
           begin
           hapus:=first;
           first:=hapus^.next;
           dispose(hapus);
           end
           else
           {menghapus node tengah atau akhir}
           Begin
                 Bantu:=first;
                 While (elemen <> bantu^.nilaihrf) and (bantu^.next <>
nil) do
                       Bantu:=bantu^.next;
                 Hapus:=bantu^.next;
                 If hapus <> nil then
                 Begin
                 If hapus <> last then {node tengah}
                       bantu^.next:=hapus^.next
                       Else
                       Begin
                             Last:=bantu;
                             Last^.next:=nil;
                       End;
                 Dispose(hapus);
                 End
                 Else
                 Writeln('Node Tidak ditemukan');

           End;
           end;
procedure readforward(var first,Last:pointer);
var bantu:pointer;
begin
           bantu:=first;
           repeat
                 write(bantu^.nilaihrf:3);
                 bantu:=bantu^.next;
           until bantu = nil;
writeln;
end;

procedure backward(bantu:pointer);
begin
      if bantu <> nil then
            begin
                  backward(bantu^.next);
                  write(bantu^.nilaihrf);
            end;
end;
Function Datafound(first:pointer; elemen:char):boolean;
Var ketemu:boolean; bantu:pointer;
Begin
      Ketemu:=false;
      Repeat
            If first^.nilaihrf = elemen then
            Ketemu:=true
            Else
            If first^.nilaihrf < elemen then
            First:=first^.next
            Else {data tidak ditemukan}
            bantu:=nil;
      Until ketemu or (first=nil);
      Datafound:=ketemu;
End;


begin
clrscr;
writeln('PROGRAM LINKED LIST');
writeln('===================');
write('1. Add In Front');writeln;
write('2. Add In Center');writeln;
write('3. Add In Back');writeln;
write('4. Delete Nodes');writeln;
write('5. Print the Nodes');writeln;
write('6. Find the node');writeln;
write('7. Exit');writeln;
repeat
write('What do you want to access [1/2/3/4/5/6/7]? ');
pil:=readkey; writeln;
case pil of
      '1':begin
                 writeln('Add Data From The Front Side'); writeln;
                       write('Type a char value :');readln(elemen);
                       InFront(First,Last,elemen);
             end;
       '2':begin
                       writeln('Add Data From The Center Side');writeln;
                       write('Type a char value :');readln(elemen);
                       InBack(First,Last,elemen);
             end;
       '3':begin
                       writeln('Add Data From The Back Side');writeln;
                       write('Type a char value :');readln(elemen);
                       InBack(First,Last,elemen);
             end;
       '4':begin
                 writeln('Delete The Nodes');writeln;
                 write('Type a char value you want to erase
:');readln(elemen);
                 DelNodes(First,Last,elemen);
            end;
      '5':begin
                 writeln('Print The Node List');writeln;
                 readforward(First,Last);writeln;
                 backward(first);
            end;
      '6':begin
                 writeln('Find The Nodes');writeln;
                 write('Type a char value :');readln(elemen);
                 Datafound(first,elemen);
            end;
end;
until pil = '7';
end.


HEADED LINKED LIST

Headed linked list adalah suatu node yang ditambahkan pada sebuah linked list dengan maksud-
maksud tertentu. Node ini tidak berisi informasi sebagai mana layaknya node yang lain, tetapi
keberadaanya akan mempercepat jalannya eksekusi. Berikut beberapa kegunaan headed linked list:

    1. Head yang dibiarkan kosong pada bagian informasinya untuk antisipasi dan membuat linked
        list pada node first tidak akan pernah nil.
    2. Bisa saja diisi dengan informasi banyaknya node yang ada..
    3. Bisa juga untuk menjumlah jumlah dari node-node yang lain.
    4. Dan yang lainnya sesuai kebuatuhan anda. Silakan definisikan sendiri.
Dengan adanya head maka kita butuh prosesdur yang sederhana untuk proses inisialisasinya yang
bertujuan untuk membentuk headed linked list:

Procedure initial(var            first:pointer);
Begin
New(first);
First^.next:=nil;
End;

Untuk selengkapnya silahkan dicoba sendiri sebagai bahan latihan.
DOUBLE LINKED LIST

Double linked list adalah ubahan dari linked lis yang selama ini kita miliki. Jika selama ini linked list
kita hanya memiliki sebuh pointer saja pada setiap node. Hal ini memberikan kerugian pada proses
pembacaan yang kurang cepat karena hanya bisa membaca 1 arah saja yaitu ke kanan atau ke kiri.
Karena nya kita membutuhkan linked list yang memliki 2 pointer di setiap ujungnya. Pointer yang
pertama akan menunjuk ke node sebelumnya dan pointer yang kedua akan menunjuk ke node
berikutnya. Jika linked list ini memiliki kepala kita menamakannya heades doubly linked list.

Dengan keadaan seperti diatas maka kita perlu menyesuaikan deklarasi simpulnya sebagai berikut:

Type pointer = ^data;
Data= record
Info : char;
Left,right:pointer;
End;
Var head:pointer;


Pada deklarasi diatas pointer left akan menunjuk node sebelumnya dan pointer right akan menunjuk
node sesudahnya. Untuk inisialisasi perlu perubahan sebagai berikut.

Procedure initial(var              head:pointer);
Begin
New(head);
      With head^ do
      Begin
      Left:=nil;
      Right:-nil;
      End;
End;

Pada dasarnya prosedur inisialisasi tidak harus ada. Karena hal ini bisa dilakukan langsung pada main
program. Namun pemekaran kode seperti ini akan membuat program lebih terstruktur.

Pada double linked list prosedur sisip dan hapusnya jadi berbeda. Berikut penjelasan masing-masing
prosedur.

MENYISIPKAN DATA

Proses oenambahan node baru pada double linked list akan membutuhkan beberapa tahap seperti
berikut ini;

   1. Pointer head menunjuk ke node head . {keadaan awal}
   2. Penambahan dimulai dengan mengatur pointer kanan pada node baru diarahkan ke node
       yang ditunjuk oleh pointer kanan dari node head. {baru^.right:=head^.right}
   3. Pointer kiri dari node baru menunjuk ke node head. {baru^.left:=head}
   4. Pointer kiri dari node sesudah node head menunjuk ke node baru. (head^.right^.left:=baru}
   5. Pointer kanan dari node head diarahkan ke node baru (head^.right:=baru}
Untuk menyisipkan data di tengah yang perlu kita lakukan adalah menambah pointer lain misal
bantu untuk mencarikan posisi yang tepat. Dan node baru akan diletakkan setelah node yang
ditunjuk oleh pointer bantu. Langkahnya sama dengan yang diatas hanya mari kita ubah pointer
head menjadi bantu.
bantu^.right:=head^.right
bantu^.left:=head
head^.right^.left:=bantu
head^.right:=bantu

untuk menyisipkan data diakhir linked list:

bantu^.right:=baru

baru^.kiri:=bantu

selengkapnya adalah sebagai berikut:

program double_linkedlist;
uses crt;
Type pointer = ^data;
      data= record
      info : char;
      left,right:pointer;
End;
var head:pointer;
pil,elemen:char;
Procedure initial(var head:pointer);
Begin
New(head);
      With head^ do
      Begin
      left:=nil;
      right:=nil;
      End;
End;
procedure addnodes(var head:pointer; elemen:char);
var baru,bantu:pointer;
begin
      new(baru);
      baru^.info:=elemen;
      if elemen > head^.left^.info then
      begin
            baru^.left:=head^.left;
            baru^.right:=head^.right;
            head^.left^.right:=baru;
            head^.left:=baru;
      end
      else
      begin
            bantu:=head;
            while bantu^.right^.info < elemen do
                  bantu:=bantu^.right;
            baru^.right:=bantu^.right;
            bantu^.right^.left:=baru;
            bantu^.right:=baru;
            baru^.left:=bantu;
      end;
end;
procedure delnodes(var head:pointer;elemen:char);
var bantu:pointer;
begin
      if head^.right = nil then
            writeln('Linked List is Empty')
      else
      begin
            bantu:=head;
            repeat
                  bantu:=bantu^.right;
            until (bantu^.info = elemen) or (bantu= head);
            if bantu^.info=elemen then
            begin
                  bantu^.left^.right:=bantu^.right;
                  bantu^.right^.left:=bantu^.left;
                  dispose(bantu);bantu:=head;
            end
            else
            writeln('Data is not found');
      end;
end;
procedure printnodes(var head:pointer);
var bantu:pointer;
begin
      bantu:=head;
            repeat
                  write(bantu^.info:3);
                  bantu:=bantu^.right;
            until bantu = nil;
writeln;
end;

BEGIN
clrscr;
{initial(head);}
writeln('PROGRAM DOUBLE LINKED LIST');
writeln('==========================');
write('1. Add Nodes');writeln;
write('2. Erase Nodes');writeln;
write('3. Print Nodes');writeln;
write('4. Exit');writeln;

repeat
write('What do you want to access [1/2/3/4]? ');
pil:=readkey; writeln;
case pil of
      '1':begin
                 writeln('Add Data'); writeln;
                 write('Type a char value :');readln(elemen);
                 addnodes(head,elemen);
            end;
      '2':begin
                 writeln('Erase Nodes');writeln;
                 write('Type a char value to erase:');readln(elemen);
                 delnodes(head,elemen);
            end;
      '3':begin
                 writeln('Print Nodes');writeln;
                 printnodes(head);
           end;
end;
until pil = '4';
END.


Contoh kedua:

Program DblLinkLingkar;
uses crt;
type
Point = ^node;
node = record
isi : integer;
next: point;
prev: point;
end;
var
P : point;
Procedure TamDepan( var A : point ; nilai : integer);
var
baru : point;
begin
      new(baru);
      baru^.isi := nilai;
      baru^.prev:= nil;
      baru^.next:= nil;
      if A = nil then
      begin
            A := baru;
            A^.next := A;
            A^.prev := A;
      end
      else
      begin
            baru^.next := A;
            baru^.prev := A^.prev;
            A^.prev^.next := baru;
            A^.prev := baru;
            A := baru;
      end;
end;
Procedure TamBelakang( var A : point ; nilai : integer);
var
baru : point;
begin
      new(baru);
      baru^.isi := nilai;
      baru^.prev:= nil;
      baru^.next:= nil;
      if A = nil then
      begin
            A := baru;
            A^.next := A;
            A^.prev := A;
      end
      else
      begin
             baru^.next := A;
             baru^.prev := A^.prev;
             A^.prev^.next := baru;
             A^.prev := baru;
      end;
end;
{**********************************************************
* Procedure menampilkan isi Link list *
**********************************************************}
Procedure Tampil(A : point);
var
bantu : point;
begin
      bantu := A;
      repeat
            write(bantu^.isi,',');
            bantu:=bantu^.next;
      until bantu = A;
end;
Procedure InsertDepan(var A:point);
var
i, jum, data : integer;
begin
      write('Jumlah data :');readln(jum);
      for i:=1 to jum do
      begin
            write('Nilai data ke-[',i,'] :');readln(data);
            TamDepan(A,data);
      end;
end;
Procedure InsertBelakang(var A:point);
var
i, jum, data : integer;
begin
      write('Jumlah data :');readln(jum);
      for i:=1 to jum do
      begin
            write('Nilai data ke-[',i,'] :');readln(data);
            TamBelakang(A,data);
      end;
end;
begin
writeln('Menambah data depan');
InsertDepan(P);
write('Hasilnya -->');
tampil(P);
writeln;
writeln('Menambah data belakang');
InsertBelakang(P);
write('Hasilnya Akhir -->');
Tampil(P);
writeln;
end.


CIRCULAR DOUBLE LINKED LIST
Circular double linled list adalah linked list yang node terakhirnya menunjuk ke node pertama dan
node pertamanya menunjuk ke node terakhir. Hasilnya linked list ini tidak memiliki nilai nil pada
bagian tail atau pada head dan tailnya jika linked list itu kita beri kepala. Sehingga analogi linked list
ini adalah seperti untaian kalung, membentuk lingkaran.

Sehingga dapat kita ambil kesimpulan:

            •       Double: artinya field pointer-nya terdiri dari dua buah dan dua arah, yaitu prev dan
                    next

            •       Linked List: artinya node-node tersebut saling terhubung satu sama lain.

            •       Circular: artinya pointer next dan prev-nya menunjuk ke dirinya sendiri




                •    Jika sudah lebih dari satu node, maka pointer prev akan menunjuk ke node
                     sebelumnya, dan pointer next akan menunjuk ke node sesudahnya.




Operasi-operasi pada circular doule linked list

Deklarasi awalan:

procedure awalan(var head:pointer);
begin
      new(head);
      with head^ do
      begin
            next:=head;
            prev:=head;
      end;
end;
Pada proses awalan saat pertama kali linked list dialokasikan memorinya maka pointer next dan prev
akan saling menunjuk di dalam dirinya sendiri. Pada proses penambahan data ada beberapa langkah
yang harus dilakukan yaitu:

   1.   Node yang ditunjuk pointer baru, pointer prevnya akan menunjuk ke node terakhir.
   2.   Pointer kanan dari node baru akan menunjuj ke node head.
   3.   Pointer next dari node terahir yang semula menunjuk ke head akan menunjuk ke node baru.
   4.   Pointer prev dari node head yang semula menunjuk ke node terakhir dibuat menunjuk ke
        node baru.




Sedangkan untuk penghapusan langkahnya adalah sebagai berikut ini:
   1. Pointer bantu digerakkkan untuk mencari node yang akan dihapus.
   2. Pointer next dari node sebelum node yang ditunjuk pointer bantu dibuat menunjuk ke node
       setelah node bantu
   3. Pointer prev dari node setelah bantu diarahkan ke node sebelum bantu
   4. Dispose bantu
Contoh program selengkapnnya adalah sebagai berikut ini:

program headed_CDLL;
uses crt;
Type pointer = ^data;
      data= record
      info : char;
      next,prev:pointer;
End;
var head :pointer;
pil,elemen:char;
procedure awalan(var head:pointer);
begin
      new(head);
      with head^ do
      begin
            next:=head;
            prev:=head;
      end;
end;
procedure addnodescdll(var head:pointer; elemen:char);
var baru,bantu:pointer;
begin
      new(baru);
      baru^.info:=elemen;
      if elemen > head^.prev^.info then
      begin
            baru^.prev:=head^.prev;
            baru^.next:=head;
            head^.prev^.next:=baru;
            head^.prev:=baru;
      end
      else
      begin
            bantu:=head;
            while bantu^.next^.info < elemen do
                  bantu:=bantu^.next;
            baru^.next:=bantu^.next;
            bantu^.next^.prev:=baru;
            baru^.prev:=bantu;
      end
end;
procedure delnodescdll(var head:pointer; elemen:char);
var bantu:pointer;
begin
      if head^.next=head then
            writeln('Empty Linked List')
      else
            begin
                  bantu:=head;
                  repeat
                        bantu:=bantu^.next;
                  until (bantu^.info=elemen) or (bantu=head);
                  if bantu^.info = elemen then
                  begin
                        bantu^.prev^.next:=bantu^.next;
                        bantu^.next^.prev:=bantu^.prev;
                        dispose(bantu);bantu:=head;
                     end
                     else
                     writeln('The data is not found');
            end;
end;
Procedure readnodes(var head : pointer);
Var bantu : pointer;
Begin
      bantu := head^.prev;
      Repeat
            write(bantu^.info:3);
            bantu := bantu^.prev;
      until (bantu=head);
End;
BEGIN
clrscr;
awalan(head);
writeln('PROGRAM HEADED CIRCULAR DOUBLE LINKED LIST');
writeln('==========================================');
write('1. Add Nodes');writeln;
write('2. Erase Nodes');writeln;
write('3. Print Nodes');writeln;
write('4. Exit');writeln;

repeat
write('What do you want to access [1/2/3/4]? ');
pil:=readkey; writeln;
case pil of
      '1':begin
                 writeln('Add Data'); writeln;
                 write('Type a char value :');readln(elemen);
                 addnodescdll(head,elemen);
            end;
      '2':begin
                 writeln('Erase Nodes');writeln;
                 write('Type a char value to erase:');readln(elemen);
                 delnodescdll(head,elemen);
            end;
      '3':begin
                 writeln('Print Nodes');
                 readnodes(head);writeln;
            end;
end;
until pil = '4';

END.


Tugas :

   1. Program diatas masih mengalami kesalahan logika, silahkan anda sekalian
      memperbaikinya.
                               QUEUE (ANTRIAN)
Saat ini kita akan membahas salah satu jenis struktur data yang disebut dengan queue alias
antrian. Jenis ini yang sering digunakan untuk mensimumulasikan keadaan dunia nyata.

PENGERTIAN QUEUE

Antrian adalah suatu kumpulan data yang mana penambahan elemen hanya bisa dilakukan
pada suatu ujung (disebut dengan rear atau sisi belakang) dan pengambilan data dilakukan
lewat ujung lainnya yang kita sebut front atau sisi depan. Sehingga prinsip kerja dari queue
ini adalah FIFO (first In First Out) atau yang pertama kali masuk adalah yang pertama keluar.
Antrian begitu banyak kita jumpai dikehidupan sehari-hari. Dalam bidang komputer antrian
bisa kita lihat saat sistem komputer sedang berbagi waktu (time sharing computer system)
dimana ada sejumlah permintaan secara serempak.

QUEUE DENGAN ARRAY

Queue adalah sejumlah kumpulan data, karenanya ada 2 tipe data yang sangat tepat dalam
mengimplementasikan queue. Pertama dengan array dan kedua dengan linked list. Mari kita
bahas dengan menggunakan array terlebih dahulu. Perhatikan ilustrasi gambar berikut ini:


                         A      B      C      D      E
Front                                                                    Rear


Gambar diatas mengilustrasikan urutan penyajian data pada queue. Data A berada diujung
terluar (akan keluar terlebih dahulu karena ia masuk terlebih dahulu. Dan jika ada yang
elemen baru masuk ia akan menjadi tetangga kanan dari elemen data terakhir. Dalam
antrian juga dikenal 2 operasi dasar untuk memasukkan data pada bagian belakang dan
menghapus data pada bagian depan. Yang harus kita perhatikan dalam penyajian queue
dengan array adalah pengecekan bahwa queue sudah penuh untuk menhindari overflow.

Deklarasi queue dengan array

const max=10;
type queue=array[1..max]of char;
var itsqueue:queue;


misal batas antrian adalah sepuluh data karakter. Untuk penambahan karakter (saat ini kita
abaikan kejadian overflow) adalah sebagai berikut:

rear:=rear+1;
itsqueue[rear]:=x;
dan untuk penghapusanya adalah sebagai berikut ini:

x:=itsqueue[front];
front:=front+1;


pada straight queue keadaan awal dibuat rear = 0 dan front =1 dan atrian akan dikatakan
kosong jika rear<front. Ketidakstabilan terjadi manakala ada ruang yang tidak dapat
dimasuki karena rear sudah = max. Mari kita ilustrasikan sebagai berikut ini;

     1. Deklarasi antrian dengan array berjumlah 5 data.
     2. Masukkan 3 data. Secara matematis menghitung jumlah data adalah rear-front+1
        atau 5-3+1=3. Dan saat ini rear adalah 3.
     3. Kemudian hapuskan 2 data, maka tersisa 1 data pada rear 3. Masukkan 2 data baru.
     4. Maka rear mencapai posisi maxnya yaitu 5. Padahal masih ada 2 ruang kosong. Tidak
        bisa ditempati karena rear sudah max.
Kecelakaan data seperti itu bisa saja diatasi dengan proses pergeseran data seperti berikut
ini:

X:=itsqueue[1];
For I:=1 to rear-1 do
Itsqueue[I]:=itsqueue[I+1];
Rear:=rear-1;

Cara kerjanya adalah:
    1. Queue yang semula tinggal satu data di rear ketiga akan digeserkan. Jika rear ada
       diposisi ketiga maka pergeseran adalah sebanyak 2 kali. Indeks queue mulai dari 1
       akan diisi dengan data dari indeks sesudahnya.
    2. Kemudian posisi rear dikurangi satu poin.
Kelihatannya solusi diatas sudah dapat mengatasi masalah, namun perhatikan dan cermati
jika ada ribuan data, berapa kali pergeseran yang dilakukan dan berapa waktu yang
dilakukan. Hal ini akan sangat membuang-buang waktu.
Permasalahan diatas akan dapat kita perbaiki dengan circular queue atau antrian berputar,
sehingga kita akan membuat data terahir sangat dekat dengan data awal. Cara kerjanya
adalah sebagai berikut ini:
    1. Misal kita memiliki 6 buah antrian array. Maka rear adalah 6.
    2. Masuk 3 buah data, maka rear adalah 6 dan front adalah 4.
    3. Kemudian masuk sebuah data baru dimana ia harus masuk melalui rear, padahal rear
       atau indeks 6 sudah terisi data, maka yang terdekat adalah indeks 1.
    4. Letakkan data disana dan rear menjadi 1. Dan begitu selanjutnya.
Selengkapnya mari perhatikan contoh program dibawah ini:

program queuearray;
uses crt;
const max=10;
type queue=array[1..max]of char;
var itsqueue:queue;
front,rear,pil:integer;
elemen:char;
procedure box;
var I : integer;
begin
      gotoxy(20,15);
      for I:=1 to max*4+1 do write('-');
      gotoxy(20,16);
      for I:=1 to max do write('|   ');
      writeln('|'); gotoxy(20,17);
      for I:=1 to max*4+1 do write('-');
      gotoxy(8,16);write('<-- front');
      gotoxy(22+max*4+1,16);writeln('<-- rear');
end;
procedure layoff(x:char; L:integer);
begin
      gotoxy(18+4*L,16); write(x);
end;
function empty(q:queue):boolean;
begin
      empty:=(front=rear);
end;
procedure addqueue(var queue1:queue; x:char);
begin
      if rear=max then rear:=1
      else rear:=rear+1;
      if not(empty(queue1)) then
      begin
            queue1[rear]:=x;
            layoff(x,rear);
      end
      else
      begin
            gotoxy(40,9); write('QUEUE IS FULL');
            repeat
            until keypressed;
            gotoxy(40,9);write(' ':30); rear:=rear-1;
            if rear=0 then
                  rear:=max;
      end;
end;
function erase(var queue1:queue):char;
begin
      if empty(queue1) then
            writeln('QUEUE IS EMPTY')
      else
      begin
            erase:=queue1[front];
            if front=max then
                  front:=1
            else front:=front+1;
      end;
end;
BEGIN
      clrscr;
      box;
      front:=0; rear:=0;
      repeat
      for pil := 5 to 9 do
       begin
            gotoxy(40,pil);write(' ':39);
      end;
      gotoxy(1,1);
      writeln('Choose Your Menu');
      writeln('================');
      writeln('1.Add the queue');
      writeln('2.Erase the queue');
      writeln('3.Exit');
      writeln('================');
      write('Pick one to do [1/2/3] : ');
      repeat
            gotoxy(22,9);writeln(' ');
            gotoxy(22,9);readln(pil);
      until (pil>=1) and (pil<=3);
            case pil of
            1:begin
                  gotoxy(40,5); writeln('Add queue');
                  gotoxy(40,6); writeln('---------');
                  gotoxy(40,8); write('type a char to fill : ');
                  readln(elemen);
                  addqueue(itsqueue,elemen);
            end;
            2:begin
                  if not(empty(itsqueue)) then
                  begin
                        elemen:=erase(itsqueue);
                        layoff(' ',front);
                  end
                  else
                  begin
                        gotoxy(30,9);
                        writeln('The queue is empty');
                        elemen:=readkey;
                  end;
                        gotoxy(30,9);write(' ':30);
            end;
      end;
until pil=3;
END.


QUEUE DENGAN POINTER

Telah kita ketahui bagaimana menyajikan antrian dengan array, dengan segala
keterbatasannya. Untuk dapat mengatasi masalah diatas dapat kita gunakan pointer sebagai
solusinya. Jika kita perhatikan aturan queue yaitu menginputkan dari belakang dan
menghapus dari belakang maka pada dasarnya ini tak ada bedanya dengan linked list. Jadi
kita bisa langsung mengimplementasikannya. Mari perhatikan contoh dibawah ini:

program pointerqueue;
uses crt;
const go='Press any key to continue';
type str10=string[10];
queue=^pointer;
pointer=record
      info:str10;
      next:queue;
      end;
var front,rear:queue;
      pil:char;
      P:char;
      plat:str10;

procedure kondisiawal(var depan,blk:queue);
begin
      new(depan);
      depan^.info:=chr(0);{nil}
      depan^.next:=depan;
      blk:=depan;
end;
procedure parkir(var depan,blk:queue; plat:str10);
var baru:queue;
begin
      new(baru);
      baru^.info:=plat;
      baru^.next:=depan;
      blk^.next:=baru;
      blk:=baru;
end;
procedure outpark(var depan,blk:queue;plat:str10);
var car,bantu:queue;
no:integer;

function found(var loc:queue; D:queue; X:str10):boolean;
var yes:boolean;
begin
      yes:=false;
      loc:=D^.next;
      repeat
            if loc^.info=X then
                  yes:=true
            else
                  loc:=loc^.next;
      until yes or(loc=D);
      found:=yes;
end;
begin
      if not(found(car,depan,plat)) then
      begin
            gotoxy(40,9);
            writeln('Your Car is not found');
            gotoxy(40,11);write(go);
            p:=readkey;
      end
      else
      if car=depan^.next then
      begin
            depan^.next:=car^.next;
            dispose(car);
      end
      else
      begin
            bantu:=depan;
           clrscr;
           write('The car Out now...');
           writeln('for a while');
           writeln;
           no:=1;
           repeat
                 bantu:=bantu^.next;
                 write('Car number ',no:3);
                 write('      Plat :');
                 writeln(bantu^.info);
                 inc(no);
           until bantu^.next^.info=plat;
           writeln; write(go);
           p:=readkey;
           bantu^.next:=car^.next;
           dispose(car);
      end;
end;
procedure readcar(depan:queue);
var bantu:queue;
no:integer;
begin
      bantu:=depan^.next;
      if bantu=depan then
      begin
            gotoxy(1,4); writeln('This Parking area is empty');writeln;
      end
      else
      begin
            no:=1;
            repeat
                  write('The car number ',no:3);
                  write('    plat: ');
                  writeln(bantu^.info);
                  bantu:=bantu^.next;
                  inc(no);
            until bantu=depan;
      end;
end;
{program utama}
begin
      kondisiawal(front,rear);
      repeat
            clrscr;
            writeln('PARKING AREA SIMULATION');
            writeln('=======================');
            writeln;
            writeln('E: Car In');
            writeln('O: Car out');
            writeln('R: Print Car Report');
            writeln('F: finish');
            writeln('=======================');
            writeln;
            write('What do you want [E/O/R/F]?: ');
            repeat
                  gotoxy(29,10);writeln(' ');
                  gotoxy(29,10);pil:=upcase(readkey);
            until pil in ['E','O','R','F'];
             case pil of
             'E':begin
                   gotoxy(40,5);writeln('CAR IN');
                   writeln;
                   gotoxy(40,7);
                   write(' Car Identitiy Number : ');
                   readln(plat);
                   parkir(front,rear,plat);
             end;
             'O':begin
                         gotoxy(40,5);writeln('CAR OUT');
                         writeln;
                         gotoxy(40,7);
                         write(' Car Identitiy Number : ');
                         readln(plat);
                         outpark(front,rear,plat);
                   end;
             'R':begin
                         clrscr;
                         writeln('The Cars data in parking area');
                         writeln('=============================');
                         readcar(front);writeln;
                         write('press any key to main menu :');
                         P:=readkey;
                   end;
             'F':begin
                         clrscr;
                         writeln('The simulation has finished');
                   end;
             end;
       until pil='F';
end.


PRIORITY QUEUE

Dalam antrian diatas, semua elemen yang masuk dalam queue dianggap memiliki prioritas
yang sama. Sehingga elemen yang masuk lebih dulu akan diproses lebih dulu, namun dalam
prakteknya elemen-elemen yang akan masuk dalam queue ada yang kita katakan
mempunyai prioritas lebiih tinggi dibanding yang lain. Ini disebut priority queue atau antrian
berprioritas

Dalam priority queue elemen yang masuk sudah ditentukan lebih dahulu prioritasnya.
Dalam hal ini berlaku 2 aturan:

    1. Elemen yang memiliki prioritas lebih tinggi akan didahulukan.
    2. Elemen yang memiliki prioritas sama akan dikerjakan sesuai dengan urutan saat
       elemen masuk queue.
Dengan memperhatikan aturan diatas maka elemen yang masuk sekalipun ia masuk
belakangan namun jika ia memiliki prioritas tinggi maka akan diproses terlebih dahulu.
Metode ini nyata saat kita perhatikan time sharing system saat ada program perprioritas
tinggi akan didahulukan dan program-program berprioritas sama akan membentuk antrian
biasa. Atau kita bisa lihat saat proses download.
Untuk bisa menyajikannya dalam bentuk pointer atau lebih tepatnya dengan linked list
terutama pada single linked list dan double linked list maka, ata ketentuan lain yang harus
diperhatikan:
    1. Setiap node memiliki tiga bagian yaitu : info, prioritas dan penyambung.
    2. Node X akan mendahului(disebelah kiri) Y jika X memiliki priorirtas yang lebih tinggi
        atau jika X dan Y berprioritas sama maka node X adalah node yang datang lebih dulu.
Dari ketentuan diatas mari kita analogikan sebuah perjalanan node baru.
    1. Terdapat queue A,S,D,F,G dengan prioritas 1,2,2,4,5.
    2. Node baru membawa info T berprioritas 3. Maka T akan diletakkan di sebelah kanan
        D (P2) dan mendahului F dan G.
    3. Kemudian masuk node baru H berprioritas 1, maka ia akan menempati posisi setelah
        A.
Untuk lebih jelasnya perhatikan contoh headed circular linked list berikut ini:


program priorqueue;
uses crt;
type queue=^data;
data=record
            info:char;
            prior:integer;
            next:queue;
      end;

var itsqueue:queue;
elemen:char;
prior:integer;

procedure kondisiawal(var PQ:queue);
begin
      new(PQ);
      PQ^.info:=chr(0);
      PQ^.prior:=0;
      PQ^.next:=PQ
end;
{procedur masuk ngantri}
procedure addqueue(var PQ:queue;X:char;P:integer);
var baru,bantu:queue;
begin
      new(baru);
      baru^.info:=X;
      baru^.prior:=P;
      baru^.next:=nil;
      {ngecek kondisi queue}
      if PQ^.next=PQ then {queue kosong}
            begin
                  baru^.next:=PQ;
                  PQ^.next:=baru;
            end
            else {sudah ada yang ngantri sebelumnya}
             begin
                     bantu:=PQ;
                     {cari posisi yang tepat}
                     while (bantu^.next^.prior <= P) and (bantu^.next <>
PQ) do
                           bantu:=bantu^.next;
                     if bantu^.next = PQ then
                     {node baru berprioritas paling rendah = sisip
belakang}
                     begin
                             baru^.next:=PQ;
                             bantu^.next:=baru;
                     end
                     else
                     {node baru berprior lebih tinggi= sisip tengah}
                     begin
                           baru^.next:=bantu^.next;
                           bantu^.next:=baru;
                     end;
            end;
end;
{cetak antrian}
procedure printqueue(PQ:queue);
var bantu:queue;
begin
bantu:=PQ^.next;
      repeat
            write('Informasi rahasia: ',bantu^.info:3);
            writeln(' berprioritas ',bantu^.prior:3);
            bantu:=bantu^.next;
      until bantu=PQ;
end;

BEGIN
clrscr;
kondisiawal(itsqueue);
writeln('Fill Information (fill priority = zero to stop)');
repeat
      write('Information, priority :');
      readln(elemen,prior);
      if prior <> 0 then
            addqueue(itsqueue,elemen,prior);
until prior = 0;
writeln;
writeln('Priority List :');writeln;
printqueue(itsqueue);
END.

Tugas :
   1. Buatlah laporan mengenai keabnormalan queue yang berupa dequeue enqueue
        ended yang merupakan keabnormalan queue yaitu masuk dan keluar bisa melalui
        rear dan front.
                                          BAB VII
                                   MULTIPLE LINKED LIST
                                 (Senarai Berantai Banyak)

Hingga saat ini telah banyak jenis senarai berantai yang kita kenal mulai yang single, double,
berkepala hingga yang berputar. Namun masih ada satu jenis lagi yang perlu kita kenal yaitu
multiple linked list (senarai berantai banyak). Senarai jenis ini sangat unik karena tidak ada
pembatasan banyaknya pointer dari sebuah node atau berapa banyaknya list yang akan
terlibat. Ini bisa disebut multilist atau list of the list. Mari kita umpamakan mendata
mahasiswa dari kampus kita STMIK EL RAHMA. Memiliki 5 jurusan (TI, SI, KA, MI & TK) dan
memiliki sejumlah mahasiswa pada masing-masing jurusannya. Misal dibawah ini adalah
data sejumlah mahasiswa dari semua jurusan :
          Jurusan                        Nama Mhs                          Kota Asal
Teknik Informatika            Hurriyatul Jannah                   Banyuwangi
                              Jaza Anil Khusna                    Purwokerto
                              Eni Kartika Sari                    Purwokerto
                              Suryahadi                           Kutoarjo
                              Arif Hidayat                        Kebumen
                              Lintang Bayu Aji                    Bantul
Sistem Informasi              Khrisna Wahyu Kusuma                Sleman
                              Wulan Irianti                       Kulonprogo
                              Basyar Addiyya                      Kebumen
                              Ghaits Rohmat                       Kebumen
                              Sulaim qamillah                     Solo
                              Iqlima Najwa                        Lampung
Komputerisasi Akuntansi       Tria Kuntirto                       Majenang
                              Jamil Ikhsan                        Ngawi
                              Wahyuningsih                        Banjarnegara
                              Istiana Handayani                   Purbalingga
Manajemen Informatika         Kurnia Fajarwati                    Banjarnegara
                              Dahlia Sri Hardiyanti               Kutoarjo
                              Herawan Bagus                       Klaten
                              Intan Nurhayati                     Magelang
                              Hindun Muhayati                     Banyuwangi
Teknik Komputer               Fajar Kurniawan                     Purwokerto
                              Agus Sholichun                      Purwokerto
                              Guntur Budiman                      Cilacap
                              Muhammad Najib                      Cilacap
                              Nurrohman                           Banjarnegara

Dari data tabel diatas, secara umum dapat kita buat urutan senarainya adalah sebagai
berikut ini:
Type pointer=^dtmhs
Dtmhs=record
Jurusan:string[25];
Nama : string[30];
Kota:string[20];
Next:pointer;
End;


Dari deklarasi diatas, memang benar data tabel diatas bisa diatasi dengan single linked list,
namun jika diperhatikan lagi, maka akan didapatkan banyak ketidak efisienan. Pertama
biasanya user akan memasukkan data secara acak, hal ini memungkinkan data yang sejenis
(misal dari jurusan yang sama) akan berjauhan letaknya. Hal ini akan menyulitkan saat data
akan disajikan. Kedua bayangkan jika jumlah mahasiswanya mencapai ribuan, padahal
jurusannya hanya 5. Maka kita akan mencatatkan jurusan sebanyak itu pula, ini berarti
BOROS. Untuk menyelesaikan permasalahan diatas yang lebih tepat adalah menggunakan
multiple linked list atau senarai berantai banyak meskipun implementasinya akan lebih
rumit.
Mari kita bandingkan deklarasi senarai berantai banyak seperti dibawah ini:

Type PointerJur=^dtjur;
Pointermhs=^dtmhs;
Dtjur=record
      Jurusan:string[25];
      Mhs:Pointermhs;
      Next:PointerJur;
      Prev:Pointerjur;
End;
Dtmhs=record
      Nama:string[30];
      Kota:string[20];
      below:Pointermhs;
End;


Dari deklarasi diatas, dapat kita bayangkan bagaimana bentuk ilustrasi penyimpanan
datanya. Ini akan tampak seperti database yang pada umumnya berlaku. Untuk lebih
lengkapnya silahkan coba program dibawah ini:

program Multilist;
uses crt;
const msgbox='THE MAJORS YOU FIND IS NOT FOUND';
msgbox1='STUDENT NAME NOT FOUND';
msgbox2='Press any key to return menu';
line='-------------------------------';
Type
pointerjur=^dtjur;
pointermhs=^dtmhs;
Dtjur=record
      jurusan:string[25];
      mhs:pointermhs;
      next:pointerJur;
      prev:pointerjur;
End;
Dtmhs=record
      nama:string[30];
      kota:string[20];
      below:pointermhs;
End;

var prodi:pointerjur;
pil:char;

{kondisi pertama }
procedure kondisiawal(var prd:pointerjur);
begin
      new(prd);
      prd^.jurusan:=chr(0);
      prd^.next:=prd;
      prd^.prev:=prd;
      prd^.mhs^.below:=nil;
end;
procedure readnodes(prd:pointerjur);
var bantujur:pointerjur;
bantumhs:pointermhs;
numjur,nummhs,N,num1,num2:integer;
begin
N:=0;
      if prd^.next=prd then writeln('the list is empty')
      else
      begin
            numjur:=0;
            clrscr;
            writeln('DAFTAR MAHASISWA');
            writeln('----------------');
            writeln;
            writeln(line, copy(line,1,27));
            write('| No. | Jurusan | No. | Nama Mahasiswa | Kota Assl
|');
            bantujur:=prd^.next;
            writeln(line, copy(line,1,27));
            {outer loop for printing majors}
            repeat
                  inc(numjur);
                  N:=15 length(bantujur^.jurusan);
                  write('|',numjur:2,'. |',bantujur^.jurusan);
                  write(' ':N,'| ');
                  bantumhs:=bantujur^.mhs^.below;
                  nummhs:=0;
                  {inner loop for print mhs}
                  repeat
                        inc(nummhs);
                        if nummhs <> 1 then
                              write('|     |',' ':17,'| ');
                        with bantumhs^ do
                        begin
                              num1:=10length(nama);
                              num2:=10length(kota);
                              write(nummhs:2,'. | ',nama);
                              write(' ':num1,'| ',kota);
                             writeln(' ':num2,'|');
                       end;
                       bantumhs:=bantumhs^.below;
                 until bantumhs=nil;
                 writeln(line, copy(line,1,27));
                 bantujur:=bantujur^.next;
           until bantujur=prd;
           writeln; write(msgbox2);readkey;
      end;
end;
procedure findmajor(var find:boolean; var bantu:pointerjur;
isprodi:string; prd:pointerjur);
begin
      find:=false;
      if prd^.next=prd then find:=false
      else
      begin
            bantu:=prd^.next;
            repeat
                  if bantu^.jurusan=isprodi then find:=true
                  else
                  bantu:=bantu^.next;
            until find or (bantu=prd);
      end;
end;
procedure findmhs(var find:boolean; var bantumhs:pointermhs;
nam:string; kot:string; x:pointerjur);
begin
      bantumhs:=x^.mhs;
      find:=false;
      repeat
            if (bantumhs^.below^.nama=nam) and
(bantumhs^.below^.kota=kot) then
                  find:=true
            else
                  bantumhs:=bantumhs^.below;
      until find or (bantumhs^.below=nil)
end;
procedure addmultilist(var prd:pointerjur);
var barujur,bantujur:pointerjur;
barumhs,bantumhs:pointermhs;
find:boolean;
nm:string[30];
kt:string[20];
jur:string[25];
lg:char;
begin
      repeat
            clrscr;
            writeln('FILL THE STUDENTS DATA');
            writeln('======================');
            write(' Student Name : ');readln(nm);
            write(' City : ');readln(kt);
            write(' Majors : ');readln(jur);
            new(barumhs);
            barumhs^.nama:=nm;
            barumhs^.kota:=kt;
            barumhs^.below:=nil;
             findmajor(find,bantujur,jur,prd);
             if not(find) then
             begin
                   new(barujur);
                   barujur^.jurusan:=jur;
                   barujur^.prev:=prd^.prev;
                   barujur^.next:=prd;
                   prd^.prev^.next:=barujur;
                   prd^.prev:=barujur;
                   prd^.prev^.mhs^.below:=barumhs;
             end
             else
             begin
                   bantumhs:=bantujur^.mhs^.below;
                   while bantumhs^.below <> nil do
                         bantumhs:=bantumhs^.below;
                   bantumhs^.below:=barumhs;
                   bantumhs:=barumhs;
             end;
             writeln;
             write('Fill more [y / N] ?');
             readln(lg);
       until (lg <> 'Y') or (lg <>'y');
end;

{nested proc, erase student or major. if major is erased all student
erase to}
procedure erase(var prd:pointerjur);
var bantujur:pointerjur;
pil,lg:char;
e_prd:string[25];
e_mhs:string[30];
e_kt:string[20];
find:boolean;
{erase student}
procedure erasemhs(var bantu:pointerjur; e_mhs:string;e_kt:string);
var bantumhs,bantumhs1:pointermhs;
p:char;
find:boolean;
begin
      findmhs(find,bantumhs,e_mhs,e_kt,bantu);
      if not(find) then {no student}
      begin
            writeln(msgbox1);
            writeln(msgbox2);
            readln(p);
      end
      else
      begin
            bantumhs1:=bantumhs^.below;
            if bantumhs1^.below=nil then
                  bantumhs^.below:=nil
            else
                  bantumhs^.below:=bantumhs1^.below;
            dispose(bantumhs1);
            if bantu^.mhs^.below=nil then
                  begin
                          bantu^.prev^.next:=bantu^.next;
                          bantu^.next^.prev:=bantu^.prev;
                          dispose(bantu);
                   end;
        end;
end;
begin
        repeat
              repeat
                    write('Erase <M>ajor or <S>tudent :');
                    pil:=upcase(readkey);
              until pil in ['M','S'];
              clrscr;
              if pil='M' then
              begin
                    writeln('ERASE THE MAJOR');
                    writeln('---------------');
                    writeln;
                    write('What major you want to delete : ');
                    readln(e_prd);
                    writeln;
                    findmajor(find,bantujur,e_prd,prd);
                    if not(find) then
                          writeln(msgbox2)
                    else
                    begin
                          bantujur^.prev^.next:=bantujur^.next;
                          bantujur^.next^.prev:=bantujur^.prev;
                          dispose(bantujur);
                    end;
              end
              else
              begin
                    writeln('ERASE THE STUDENT');
                    writeln('-----------------');
                    writeln;
                    write(' Student IdName : '); readln(e_mhs);
                    write(' City : '); readln(e_kt);
                    write(' Major : '); readln(e_prd);
                    writeln;
                    findmajor(find,bantujur,e_prd,prd);
                    if not(find) then
                          writeln(msgbox1)
                    else
                          erasemhs(bantujur,e_mhs,e_kt);
              end;
              readnodes(prd);
              writeln;
              write('Erase More [Y/N] ? ');
              lg:=upcase(readkey);

      until lg <> 'Y'
end;
procedure update(var prd:pointerjur);
var bantujur:pointerjur;
bantumhs:pointermhs;
nm:string[30];
kt:string[20];
jur:string[25];
lg:char;
find,find1:boolean;
begin
      repeat
            clrscr;
            writeln('UPDATE THE STUDENT DATA');
            writeln('-----------------------');
            writeln('Previous Data : ');
            write('Student Idname : '); readln(nm);
            write('city : '); readln(kt);
            write('Major : '); readln(jur);
            writeln;
            findmajor(find,bantujur,jur,prd);
            if not(find) then
                  writeln(msgbox)
            else
            begin
                  findmhs(find1,bantumhs,nm,kt,bantujur);
                  if not(find1) then
                        writeln(msgbox1)
                  else
                  begin
                        gotoxy(40,4); writeln('DATA UPDATE');
                        gotoxy(40,5); write(' Student Idname : ');
readln(nm);
                        gotoxy(40,6); write(' City : '); readln(kt);
                        with bantumhs^.below^ do
                              begin
                                    nama:=nm;
                                    kota:=kt;
                              end;
                  end;
            end;
            writeln;
            write(' Update More [Y/N] ?'); lg:=upcase(readkey);
      until lg <> 'Y'
end;
BEGIN
kondisiawal(prodi);
repeat
      clrscr;
      write('THE MULTILIST PROJECT');
      writeln('-------------------');
      writeln;
      writeln('1. Fill Student Data ');
      writeln('2. Erase The Data');
      writeln('3. Update data ');
      writeln('4. Print data ');
      writeln('5. Exit ');
      writeln;
      write('What do you want to do [1/2/3/4/5] ?'); readln(pil);
      repeat
      until pil in ['1','2','3','4','5'];
      clrscr;
      case pil of
      '1' : addmultilist(prodi);
      '2' : erase(prodi);
      '3' : update(prodi);
      '4' : readnodes(prodi);
      '5' : begin
                       writeln('FINISHED');
                       writeln('--------');
            end
      end;
until pil = '5'

END.

Aplikasi multiple linked list juga tidak terbatas seperti diatas saja tetapi juga bisa digunakan
untuk pembuatan skema matriks yang kita sebut matriks jarang ( sparse matrik). Sparse
matriks adalah matrik yang unik karena memili jumlah notasi tak nol yang sangat jarang.
Notasi matrik seperti ini biasanya digunakan para ilmuwan ahli genetika untuk menentukan
struktur kromosom atau DNA makhluk hidup agar bisa didapatkan bibit unggul atau
ditelusuri asal muasalnya. Atau para engineer untuk mencari celah kelemahan atau solusi
kelemahan produk yang biasanya berupa keramik atau bangunan dsb.
                                               BAB VIII
                                       TREE (STRUKTUR POHON)

    Pada bab-bab sebelumnya telah kita kenal berbagai macam jenis struktur data, namun
    kebanyakan atau bahkan hampir semuanya bersifat linier. Hanya multiple linked list yang
    tidak bersifat linier (ia tidak dikategorikan struktur data linier). Kali ini kita akan membahas
    jenis struktur data tak linier, yang memiliki sifat-sifat dan ciri-ciri khusus yang dinamakan
    tree (pohon). Struktur ini biasa digunakan untuk menggambarkan hubungan yang bersifat
    hirarkis antara elemen-elemen yang ada. Contoh paling sederhananya adalah saat
    seseorang membicarakan silsisah keluarganya (pohon keluarga). Contoh dalam bidang
    komputerisasi adalah semisal program ahli dokter (menelusur penyakit berdasarkan
    gejalanya). Perhatikan contoh silsilah penting berikut ini:


         Level 0                               Samudra Pramudibyo




 Aini Anggraini            Harun Mawaddi         Gagah Prawiro              Kinar Yasmin           Level 1



Dhiya Safina       Ghaits Allathif   Sa’adah     Aziz Azzukhruf       Kautsar Wadhih       Bintu Halwah


     Dari gambar diatas dapat diimplementasikan dengan struktur data pascal tree.           Level 2
       A. ISTILAH-ISTILAH DASAR
           Root :akar adalah node tertinggi dari tree, ia tidak punya parent.
           Parent :orang tua, adalah child dari root namun ia juga sebagai root.
           Children:anak, adalah node yang berada tepat dibawah level root atau parentnya.
           Ancestor :leluhur, adalah jika root atau parent telah memiliki 2 level turunan atau
           lebih dalam satu jalur.
           Descendent :keturunan, adalah node yang memiliki 2 level atau lebih keatas.
           Sibling : saudara, node yang memiliki parent sama.
           Leaves: daun, adalah node yang tidak lagi mempunyai child sering juga disebut
           external nodes.
           Forest : hutan adalah kumpulan sejumlah pohon yang tidak saling berhubungan.
           Degree: derajad adalah sejumlah child yang dimiliki masing-masing node, mereka
           yang memiliki child disebut juga internal nodes.
           Height/depth: adalah tingkat terdalam adalah tingkat maksimum suatu pohon
           dikurangi 1.
   Secara sederhana tree bisa didefinisikan sebagai kumpulan elemen yang salah satu
   elemennya disebut root (akar) dan sisa elemen lainya terpecah menjadi sejumlah
   himpunan yang saling tidak berhubungan satu sama lain yang disebut dengan
   subtree (sub pohon) atau cabang. Dan masing-masing subtree juga bisa mempunyai
   cabang ataupun rootnya sendiri. Pada gambar diatas yang menjadi root adalah node
   atau vertex yang berisi info Samudra Pramudibyo. Root SP memiliki 4 subtree yaitu
   AA, HM, GP dan KY. Subtree tersebut sekaligus menjadi root bagi subtree
   dibawahnya. Vertex yang tidak menjadi root dan tidak mempunyai subtree disebut
   leaves.
   Ada beberapa pohon yang akan kita kenali. Pertama adala ordered-tree dan binary-
   tree. Ordered tree (pohon beraturan) adalah jenis pohon yang mana children dari
   masing-masing node sudah ditentukan atau dengan kata lain urutan hubungan
   masing-masing node dengan lainnya sangat diperhatikan.

B. POHON BINER
   Pohon biner adalah jenis tree yang unik dalam struktur data. Ia adalah suatu
   kumpulan simpul yang mungkin kosong, atau mempunyai akar dan 2 child yang
   saling terpisah yang disebut leftchild dan rightchild. Pohon biner sangat penting
   karena banyak penerapan yang menggunakan pohon biner. Salah satunya adalah
   pada unix atau DOS/windows file system.

   Jenis-jenis pohon biner :

      Sebuah pohon biner berakar (rooted binary tree) adalah sebuah tree berakar
       dimana setiap simpul paling banyak mempunyai dua anak
      Sebuah pohon biner penuh (full binary tree), atau pohon biner asli (proper
       binary tree), adalah sebuah pohon dimana setiap simpul mempunyai nol atau
       dua anak.
      Sebuah pohon biner sempurna (perfect binary tree) (atau kadang-
       kadang pohon biner lengkap (complete binary tree) adalah sebuah pohon biner
       penuh dimana semua daunmemiliki kedalaman yang sama.
      Sebuah pohon biner lengkap (complete binary tree) dapat didefinisikan juga
       sebagai sebuah pohon biner penuh dimana semua daunnya memiliki
       kedalanam n atau n-1 untuk beberapa n. Agar sebuah pohon dapat menjadi
       sebuah pohon biner lengkap, semua anak pada tingkat terakhir harus
       menempati titik terkiri secara teratur, dengan tidak ada titik yang menganggur
       diantara keduanya. Sebagai contoh, jika dua simpul pada tingkat terbawah
       masing-masing menempati sebuah titik dengan suatu titik kosong diantara
       keduanya, tetapi sisa simpul anaknya terhimpit tanpa titik diantaranya, maka
       pohon tersebut tidak dapat membentuk sebuah pohon biner lengkap karena
       titik kosong tersebut.
      Sebuah pohon biner lengkap berakar (rooted complete binary tree) .
      Sebuah pohon biner hampir lengkap (almost complete binary tree) adalah
       sebuah pohon dimana setiap simpul yang mempunyai anak kanan juga memiliki
       anak kiri. Memiliki anak kiri tidak memerlukan sebuah simpul untuk mempunyai
       anak kanan. Penjelasan lainnya, sebuah pohon biner hampir lengkap adalah
       sebuah pohon dimana untuk sebuah anak kanan, selalu terdapat anak kiri, tetapi
       untuk sebuah anak kiri, tidak selalu terdapat sebuah anak kanan.
      pohon biner miring (skewed binary tree) adalah pohon biner yang banyaknya
       node dikiri tidak seimbang dengan banyaknya node di kanan.

       Dengan memperhatikan sembarang pohon biner kita dapatkan notasi untuk
      banyaknya node maksimum pada tingkat N adalah 2(n-1). Sehingga banyaknya
      node maksimum sampai tingkat N adalah:        2(I-1)=2N-1
   Maka jika kita memiliki pohon biner bertingkat 5 maka banyaknya daun adalah
   2*2*2*2=16 dan banyaknya node bukan daun termasuk root adalah:
   1+2+4+8+16=31; maka banyaknya node bukan daun adalah : 31-16=15;

C. PENYAJIAN POHON BINER
   Dalam menyajikan pohon biner dapat dilakukan dalam beberapa cara yaitu dengan
   berurutan dan senarai berantai. Kita akan membahas hanya dengan senarai
   berantai.
   Deklarasi Pohon:
   Jika kita perhatikan bahwa dalam setiap node tree memiliki dua pointer penunjuk
   yaitu kanan dan kiri dan sebuah informasi. Dengan begitu kita dapat
   menggambarkannya seperti berikut ini:

                       Left      Info      right

   Deklarasi dalam pascal adalah sebagai berikut:
   Type pointertree=^tree
   Tree=record
          Info:integer;
          Left,right:pointertree;
   End;


D. KUNJUNGAN/TRAVERSE
   Dalam sebuah tree banyak hal yang bisa dilakukan, namun yang paling sering
   dilakukan adalah kunjungan. Artinya kita akan mengunjungi masing-masing node
   baik untuk mencetak atau mencari. Perlu kita ketahui bahwa penatan data dalam
   binary tree ada aturannya, yaitu:
     1. Data yang lebih kecil dari rootnya akan diletakkan sebagai leftchild dan yang
        lebih besar akan menjadi right tree.
     2. Meski tree tidak lengkap aturan tetap berlaku.
     Dalam melakukan kunjungan pun binary tree punya aturannya/cara sendiri, yaitu:
     1. Kunjungan PreOrder/depth first order langkah kunjungannya adalah:
           Cetak isi node yang dikunjungi
           Kunjungi node cabang kiri
           Kunjungi node cabang kanan
     2. Kunjungan InOrder/symetric order langkah kunjungannya adalah:
           Kunjungi node cabang kiri
           Cetak isi node yang dikunjungi
           Kunjungi node cabang kanan
     3. Kunjungan PostOrder langkah kunjungannya adalah :
           Kunjungi node cabang kiri
           Kunjungi node cabang kanan
           Cetak isi node yang dikunjungi

     Untuk lebih memahaminya cobalah program dibawah ini:

program binary_tree;
uses crt;
Type pohon=^node;
      node=record
      data:integer;
      kiri,kanan:pohon;
end;
var T:pohon;
info:integer;
{--------------------------------------------------------------------}
Procedure Buat_Bitree(info :integer;var T:pohon);
var b:pohon;
begin
      if T=nil then
      begin
            new(b);b^.data:=info;b^.kiri:=nil;b^.kanan:=nil;
            T:=b;
      end
      else
      begin
            if T^.data<info then
            Buat_Bitree(info,T^.kanan);
            if T^.data>info then
            Buat_Bitree(info,T^.kiri);
      end;
end;
{--------------------------------------------------------------------}
Procedure Baca_Bitree_pre(b:pohon);
begin
      if (b<>nil) then
      begin
            write(b^.data);
           Baca_Bitree_pre(b^.kiri);
           Baca_Bitree_pre(b^.kanan);
      end;
end;
{--------------------------------------------------------------------}
Procedure Baca_Bitree_in(b:pohon);
begin
      if (b<>nil) then
      begin
            Baca_Bitree_in(b^.kiri);
            write(b^.data);
            Baca_Bitree_in(b^.kanan);
      end;
end;
{--------------------------------------------------------------------}
Procedure Baca_Bitree_post(b:pohon);
begin
      if (b<>nil) then
      begin
            Baca_Bitree_post(b^.kiri);
            Baca_Bitree_post(b^.kanan);
            write(b^.data);
      end;
end;
{--------------------------------------------------------------------}
begin
clrscr;
      new(T);T^.kiri:=nil;T^.kanan:=nil;
      writeln('Memasukkan data ke dalam tree');
      repeat
            write('Nilai data : ');readln(info);
            if info<>0 then Buat_Bitree(info,T);
      until info=0;
      writeln;
      readln;
      writeln('Pembacaan secara Pre order');
            baca_Bitree_pre(T);
      writeln;
      readln;
      writeln('Pembacaan secara In order');
            baca_Bitree_in(T);
      writeln;
      readln;
      writeln('Pembacaan secara Post order');
            baca_Bitree_post(T);
writeln;
end.

program untitled;
uses crt;
type Ptree=^pointer;
pointer=record
      isi:byte;
      kanan,kiri:Ptree;
      end;
var x,y,pil: byte;
tree,root:Ptree;
procedure kondisiawal;
begin
      root:=nil; tree:=nil;
end;
procedure erase;
begin
      if root <> nil then
      begin
            tree:=root; dispose(tree); root:=nil;
      end;
end;
procedure dataenter(var tree:Ptree; bil:byte);
begin
      if tree = nil then
      begin
            new(tree);
            tree^.isi:=bil;
            tree^.kanan:=nil;
            tree^.kiri:=nil;
      end
      else
      if tree^.isi < bil then
            dataenter(tree^.kanan,bil)
      else
      dataenter(tree^.kiri,bil);
end;
procedure found(var ketemu:boolean; tree:Ptree; angka:byte);
begin
      ketemu:=false;
      if tree=nil then
      begin
            if tree^.isi=angka then
                  begin
                  ketemu:=true; exit;
                  end;
                  found(ketemu,tree^.kiri,angka);
                  if not(ketemu) then
                  found(ketemu,tree^.kanan,angka);
      end;
end;
procedure gambar(var tree:Ptree; x,y,sel:byte);
var i:byte;
begin
      GotoXY(x,y); write(tree^.isi);
      if (tree^.kiri <> nil) or (tree^.kanan <> nil) then
      begin
            gotoxy(x-sel,y+1);write(chr(218));
            gotoxy(x+sel,y+1);write(chr(191));
            for i:=(x-sel)+1 to (x+sel)-1 do
            begin
                  gotoxy(i,y+1);write('-');
            end;
            gotoxy(x,y+1);write(chr(193));
      end;
      inc(y,2);
      if tree^.kiri<>nil then gambar(tree^.kiri, x-sel, y, sel div 2);
      if tree^.kanan<>nil then gambar(tree^.kanan, x+sel, y, sel div
2);
end;
procedure ceklevel(var tree:Ptree; var level:byte; bil:byte);
begin
      if tree<>nil then
      begin
            inc(level);
            if tree^.isi < bil then
            ceklevel(tree^.kanan,level,bil)
            else
            ceklevel(tree^.kiri,level,bil);
      end;
end;
procedure sisip;
var isi,level:byte;
ketemu:boolean;
begin
      repeat
            clrscr;
            gotoxy(30,1);write('SISIPKAN BINARY SEARCH TREE');
            gotoxy(27,2);write('===========================');
            if root <> nil then gambar(root,40,5,20);
            repeat
                  gotoxy(3,4);clreol; write('Sisip [max level=5] :');
                  readln(isi);
            until isi in [0..100];
            if isi=0 then exit;
            level := 1;
            ceklevel(root,level, isi);
            found(ketemu,root,isi);
            if (not ketemu) and (level<=5) then
                  dataenter(root,isi)
            else
            begin
                  textcolor(12);
                  gotoxy(3,5);write('level maks/ bil sudah ada');
                  delay(750);
                  textcolor(15);
            end;
      until isi=0;
end;
procedure delete(var tree:Ptree; bil:byte);
var bantu:Ptree;
begin
      if tree = nil then
      begin
            textcolor(12);gotoxy(2,4);write(bil,' not found');
            textcolor(15);
      end else
      if bil < tree^.isi then delete(tree^.kiri,bil)
      else
      if bil > tree^.isi then delete(tree^.kanan,bil)
      else
      if tree^.kanan=nil then
      begin
            bantu:=tree;
            bantu:=bantu^.kanan;
            dispose(tree);
            tree:=bantu;
      end else
     begin
             bantu:=tree^.kanan;
             while bantu^.kiri <> nil do
             bantu:=bantu^.kiri;
             tree^.isi := bantu^.isi;
             delete(tree^.kanan,bantu^.isi);
      end;
end;
procedure update;
var ketemu:boolean;
bil,bil2,level:byte;
begin
      repeat
            clrscr;
            gotoxy(30,1);write('Update Binary search Tree');
            gotoxy(27,2);write('============================');
            if root <> nil then
                  gambar(root,40,5,20);
            gotoxy(2,3);write('Update [0-->Exit]= '); readln(bil);
            found(ketemu,root,bil);
            if not ketemu then
            begin
                  gotoxy(2,4);write(bil,' not found');
            end else
            begin
                  gotoxy(2,4);write('dengan :');readln(bil2);
                  found(ketemu,root,bil2);
                  level:=1;
                  ceklevel(root,level,bil2);
                  if (not ketemu) and (level<=5) then
                  begin
                        delete(root,bil);
                        dataenter(root,bil2);
                  end else
                  begin
                        textcolor(12);
                        gotoxy(3,5);write('Bil sudah ada/level sudah
max');
                        delay(750); textcolor(15);
                  end;
            end;
      until bil=0;
end;
procedure preorder(tree:Ptree);
begin
      if tree = nil then
      begin
            gotoxy(x,y);write(tree^.isi); inc(x,3);
            preorder(tree^.kiri);
            preorder(tree^.kanan);
      end;
end;
procedure inorder(tree:Ptree);
begin
      if tree = nil then
      begin
            inorder(tree^.kiri);
            gotoxy(x,y);write(tree^.isi); inc(x,3);
               inorder(tree^.kanan);
        end;
end;
procedure postorder(tree:Ptree);
begin
      if tree = nil then
      begin
            postorder(tree^.kiri);
            postorder(tree^.kanan);
            gotoxy(x,y);write(tree^.isi); inc(x,3);
      end;
end;
procedure search(var tree:Ptree; X,Y,selisih,cari:byte);
begin
      inc(y,2);
      if cari < tree^.isi then
      begin
            if tree^.kiri <> nil then
            search(tree^.kiri, x+selisih, y, selisih div 2, cari);
      end else
      if cari > tree^.isi then
      begin
            if tree^.kanan <> nil then
            search(tree^.kanan,x+selisih, y, selisih div 2, cari);
      end else
      if cari = tree^.isi then
      begin
            dec(y,2);
            gotoxy(x,y); textcolor(12); write(cari);
            gotoxy(2,4); write(cari,' ketemu');
            readkey;
            gotoxy(x,y); textcolor(15); write(cari);
            gotoxy(2,4);write('':20);
      end else
      if ((tree^.kiri=nil) or (tree^.kanan=nil)) and (cari<>tree^.isi)
then
      begin
            gotoxy(2,4);write(cari,' Not Found');delay(750);
            gotoxy(2,4);write('':20);
      end;
end;
procedure menu;
var bil,pil:byte;

begin
        clrscr;
        gotoxy(35,3);write('Menu Binary Search tree');
        gotoxy(23,4);write('=============================');
        gotoxy(28,6);write('1. Ciptakan ');
        gotoxy(28,7);write('2. Masukkan ');
        gotoxy(28,8);write('3. Hapus ');
        gotoxy(28,9);write('4. Cari ');
        gotoxy(28,10);write('5. Update ');
        gotoxy(28,11);write('6. Traverse ');
        gotoxy(28,12);write('7. Bersihkan ');
        gotoxy(28,13);write('8. Exit ');
        repeat
              gotoxy(25,15);clreol;write('Pilihanmu [1..8] : ');
             readln(pil);
       until pil in [1..8];
       case pil of
       1:kondisiawal;
       2:sisip;
       3:begin
                   repeat
                         clrscr;
                         gotoxy(30,1);write('Hapus Binary Search tree');

       gotoxy(37,2);write('============================');
                        if root <> nil then gambar(root,40,5,20);
                        gotoxy(2,3);write('hapus[0-->exit]= ');
                        readln(bil);
                        delete(root,bil);
                  until bil=0;
             end;
       4:begin
                  repeat
                        clrscr;
                        gotoxy(30,1);write('Search Binary Search tree');

       gotoxy(27,2);write('=============================');
                        if root <> nil then gambar(root,40,5,20);
                        gotoxy(2,3);write('search[0-->exit] : ');
                        readln(bil);
                        if bil <> 0 then search(root,40,5,20,bil);
                  until bil=0;
             end;
       5:update;
       6:begin
                  clrscr;
                  gotoxy(25,1);write('Traverse Binary Search tree');

       gotoxy(23,2);write('================================');
                  if root <> nil then gambar(root,40,5,20);
                  gotoxy(36,15);write('PREORDER:');
                  gotoxy(25,16);write('***************************');
                  x:=1;y:=17;preorder(root);
                  gotoxy(36,15);write('INORDER:');
                  gotoxy(25,16);write('***************************');
                  x:=1;y:=20;inorder(root);
                  gotoxy(36,15);write('POSTORDER:');
                  gotoxy(25,16);write('***************************');
                  x:=1;y:=23;postorder(root);
             end;
       7:begin erase; kondisiawal; end;
       8:exit;
       end;
end;

BEGIN
pil:=0;
      textcolor(15);
      repeat
            menu;
      until pil=8;
      erase;
END.

program binary_tree;
uses crt;
Type pohon=^tree;
      tree=record
      data:char;
      kiri,kanan:pohon;
end;
var T:pohon;
info:char;
{--------------------------------------------------------------------}
Procedure Buat_Bitree(info:char;var T:pohon);
var b:pohon;
begin
      if T=nil then
      begin
            new(b);b^.data:=info;b^.kiri:=nil;b^.kanan:=nil;
            T:=b;
      end
      else
      begin
            if T^.data<info then
            Buat_Bitree(info,T^.kanan);
            if T^.data>info then
            Buat_Bitree(info,T^.kiri);
      end;
end;
{--------------------------------------------------------------------}
Procedure Baca_Bitree_pre(b:pohon);
begin
      if (b<>nil) then
      begin
            write(b^.data:3);
            Baca_Bitree_pre(b^.kiri);
            Baca_Bitree_pre(b^.kanan);
      end;
end;
{--------------------------------------------------------------------}
Procedure Baca_Bitree_in(b:pohon);
begin
      if (b<>nil) then
      begin
            Baca_Bitree_in(b^.kiri);
            write(b^.data:3);
            Baca_Bitree_in(b^.kanan);
      end;
end;
{--------------------------------------------------------------------}
Procedure Baca_Bitree_post(b:pohon);
begin
      if (b<>nil) then
      begin
            Baca_Bitree_post(b^.kiri);
            Baca_Bitree_post(b^.kanan);
            write(b^.data:3);
      end;
end;
{--------------------------------------------------------------------}
begin
clrscr;
      new(T);T^.kiri:=nil;T^.kanan:=nil;
      writeln('Memasukkan data ke dalam tree');
      repeat
            write('Nilai data : ');readln(info);
            if info<>'x' then Buat_Bitree(info,T);
      until info='x';
      writeln;
      readln;
      writeln('Pembacaan secara Pre order');
            baca_Bitree_pre(T);
      writeln;
      readln;
      writeln('Pembacaan secara In order');
            baca_Bitree_in(T);
      writeln;
      readln;
      writeln('Pembacaan secara Post order');
            baca_Bitree_post(T);
writeln;
write(chr(02));write(chr(218));
writeln;
end.


  E. TEKNIK TRAVERSE
     Perhatikanlah binary search tree berikut ini:


                                 H       0                              Tingkat 0


                                                                        Tingkat 1
               1       A                         K       2




                           C              J          L                  Tingkat 2
                       3             6                       7



           4       B             D                                      Tingkat 3
                                         5




     Dari pohon biner diatas mari kita telusur untuk mencari hasil yang diperoleh dari
     traverse PreOrder, InOrder dan PostOrder.

     PREORDER (cetak,kunjungi kiri,kunjungi kanan)
    Tingkat         Pemanggilan Procedur               Isi Simpul   Karakter cetak
0             Write0.info                       H                  H
0             Preorder0.kiri                    A
1                 Write1.info                   A                  A
1                 Preorder1.kiri                Nil
              Kembali ke parent (1)
1                 Preorder1.kanan               C
2              Write3.info                      C                  C
2             Preorder3.kiri                    B
3                 Write4.info                   B                  B
3                 Preorder4.kiri                Nil
              Kembali ke parent (3)
3                 Preorder4.kanan               Nil
              Kembali ke parent (2)
2             Preorder3.kanan                   D
3             Write5.info                       D                  D
3             Preorder5.kiri                    Nil
              Kembali ke parent (3)
3             Preorder5.kanan                   Nil
              Kembali ke parent (2)
              Kembali ke parent (1)
              Kembali ke parent (0)
0             Preorder0.kanan                   K
1             Write2.info                       K                  K
1             Preorder2.kiri                    J
2                 Write6.info                   J                  J
2                 Preorder6.kiri                Nil
              Kembali ke parent (2)
                  Preorder6.kanan               Nil
              Kembali ke parent(1)
1             Preorder2.kanan                   L
2                 Write7.info                   L                  L
2                 Preorder7.kiri                Nil
              Kembali ke parent (2)
2                 Preorder7.kanan               Nil
              Kembali ke parent (1)
              Kembali ke parent (0)
              Selesai

Maka karakter tercetak adalah: H A C B D K J L
Dalam program akan tercetak seperti gambar dibawah berikut ini:
   Tugas :
   1. Buktikan dengan penelusuran rekursif bahwa pembacaan secara inorder dan
      postorder akan menghasilkan nilai seperti tersebut diatas.
F. KONVERSI INFIX, POSTFIX DAN PREFIX

   Ada tiga bentuk penulisan notasi matematis di komputer, satu bentuk adalah yang
   umum digunakan manusia (sebagai input di komputer) yaitu infix, dan dua yang
   digunakan oleh komputer (sebagai proses), yaitu postfix dan infix. Berikut contoh-
   contohnya:

    NO            INFIX                    POSTFIX                      PREFIX
   1      A+B                      AB+                        +AB
   2      (A + B) * C              AB+C*                      *+ABC
   3      A * ( B + C)             ABC+*                      *A+BC

   Cara Membuat Notasi Prefix, Infix, dan Postfix (hendriprihandono.wordpress.com)

   Dalam struktur data yang banyak dipelajari, kita ketahui adanya 3 notasi operasi
   yang dilakukan untuk suatu operasi aritmatika, yaitu prefix, infix, dan postfix.
   Sebelum kita kupas mengenai notasi di atas, perlu dipahami terlebih dahulu
   indikator yang membentuk terjadinya notasi dalam struktur data. Notasi terbentuk
   dari operand dan operator. Operand adalah data atau nilai yang membantu dalam
   proses sedangkan operator adalah fungsi yang digunakan dalam proses.

   Contoh :

   A+B*C

   2+3*5

   Keterangan : A, B, C, 2, 3, 5 adalah operand
   +, * adalah operator
   level/hirarkhi dari operator:
   1. ^ (pangkat)

   2. * (kali) atau / (bagi)

   3. + (jumlah) atau – (kurang)

 Prefix

   yaitu notasi yang terbentuk atas operator dengan operand, dimana operator berada
   didepan operand.

   Contoh : A + B * C (Infix)
   maka notasi prefixnya adalah +A*BC
   Pemecahannya :
   A + B * C

   diketahaui ada 3 operand yaitu : A, B, C, dan 2 operator yaitu : +, *. Proses dimulai
   dengan melihat dari hirarkhi operator. Contoh diatas operator yang tertinggi adalah
   * kemudian +.

   Tanda * diapit oleh dua operand yaitu B dan C yaitu B * C , prefixnya dengan
   menggabungkan operand dan memindahkan operator kedepan 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 2 operand, yaitu A dan *BC,
   gabungkan operand, sehingga menjadi A*BC, lalu pindahkan operator kedepan
   operand, sehingga hasil akhir menjadi
   + A * B C.

 Infix

   yaitu notasi yang terbentuk atas operator dengan operand, dimana operator berada
   diantara operand. Notasi ini hanya dikenal oleh manusia dan selalu digunakan dalam
   perhitungan aritmatika.

   Contoh : A + B * C

   (A+B)*C

   A–(B+C)*D^E

 Postfix

   yaitu notasi yang terbentuk atas operator dengan operand, dimana operator berada
   dibelakang operand. Notasi ini hanya dikenal oleh processor dan dipahami dalam
   ALU (Arithmetic And Logic Unit ). Adalah salah satu bagian dalam dari sebuah
   mikroprosesor         yang      berfungsi      untuk      melakukan       operasi
   hitungan aritmatika dan logika.
     Contoh : A + B * C (Infix)
     maka notasi postfixnya adalah ABC*+
     Pemecahannya :
     A + B * C

     diketahaui ada 3 operand yaitu : A, B, C, dan 2 operator yaitu : +, *. Proses dimulai
     dengan melihat dari hirarkhi operator. Contoh diatas operator yang tertinggi adalah
     * kemudian +.

     Tanda * diapit oleh dua operand yaitu B dan C yaitu B * C , postfixnya dengan
     menggabungkan operand B dan C menjadi BC lalu memindahkan operator ke
     belakang operand C, sehingga fungsi B * C, notasi postfixnya menjadi BC*. Sehingga
     hasil sementara dari notasi postfix adalah
     A + BC*
     selanjutnya mencari postfix untuk operator yang berikutnya, yaitu +, cara yang
     dilakukan sama seperti di atas, operator +, diapit oleh 2 operand, yaitu A dan BC*,
     gabungkan operand tersebut, sehingga menjadi ABC*, lalu pindahkan operator + ke
     belakang operand ABC*, sehingga hasil akhir menjadi
     ABC*+

     Silakan dicoba program berikut ini:
program konversi_infix_postfix_prefix;
uses crt;
const Gr='------------------';
Operator1 = ['+','-','*','/','^'];
Operand = ['A'..'Z'];
type tree=^simpul;
stack=^data;
simpul=record
      info:char;
      kiri,kanan:tree;
end;
data=record
      item:tree;
      next:stack;
end;
var Pohon:tree;
Infix:string;
betul:boolean;
I:integer;
lagi,Gg:char;

procedure tampilan;
var P:char;
begin
      gotoxy(11,5);
      writeln('-------------------------------------------------------
');
      writeln('| MENGUBAH NOTASI INFIX MENJADI PREFIX DAN POSTFIX
|');
      writeln('|       dengan menggunakan bantuan binary tree
|');
      writeln('|    Operator yang diterima adalah ^,*,/,+ dan -
|');
       writeln('|
|');
       writeln('|      Tekan <RETURN> untuk mulai proses ...
|');
       gotoxy(11,whereY);
       writeln('-------------------------------------------------------
');
       P:=readkey;
       clrscr;
end;
{alokasi node}
function P_simpul(hrf:char):tree;
var baru:tree;
begin
      new(baru);
      baru^.info:=hrf;
      baru^.kanan:=nil;
      baru^.kiri:=nil;
      P_simpul:=baru;
end;
{alokasi elemen stack}
function T_simpul(hrf:tree):stack;
var baru:stack;
begin
      new(baru);
      baru^.item:=hrf;
      baru^.next:=nil;
      T_simpul:=baru;
end;
{push elemen ke stack}
procedure push(var S:stack; T:tree);
var B:stack;
begin
      B:=T_simpul(T);
      if S=nil then
            S:=B {tump kosong}
      else
      begin
            B^.next:=S;
            S:=B
      end
end;
{pop elemen}
procedure pop(var S:stack; var T:tree);
var bantu:stack;
begin
      if S <> nil then
            begin
                  bantu:=S;
                  T:=S^.item;
                  S:=S^.next;
                  dispose(bantu);
            end
end;
{menentukan valensi/keutamaan operator}
function valensi(dt:char):integer;
begin
      case dt of
     '^' : valensi:=3;
     '*','/' : valensi :=2;
     '+','-' : valensi :=1;
     '(' : valensi :=0;
     end
end;
procedure cetak_stack(S:stack);
begin
      while S <> nil do
      begin
            write(S^.item^.info,' ');
            S:=S^.next;
      end;
      writeln;
end;
procedure buat_pohon(var pohon:tree; var betul:boolean; Ung:string);
var I :integer;
Pd,Gg :char;
S_phn, T1,T2,St:tree;
Opr,Opn:stack;

function gabung:tree;
begin
      pop(Opn,T1); {cabang kanan}
      pop(opn,T2); {cabang kiri}
      pop(opr,St); {root}
      St^.kanan:=T1;
      St^.kiri:=T2;
      gabung:=St;
end;
{program procedure}
begin
      betul:=true;
      Opr:=nil;
      Opn:=nil;
      write('PROSES PEMBENTUKAN PELACAKAN POHON BINER');
      writeln;
      writeln(Gr,Gr,Gr);
      writeln('Karakter dibaca       Tumpukan Operator     Tumpukan
Operand');
      write(' ':22,chr(218),Gg,Gg,' Ujung ');
      writeln('tumpukan',Gg,Gg,chr(191));
      writeln(' ':22,chr(25),' ':21,chr(25));
      writeln(Gr,Gr,Gr);

     {start porcess}
     for I:=1 to length(Ung) do
     begin
           Pd:=upcase(Ung[I]);
           gotoxy(8,wherey); write(Pd);
           if Pd <> ' ' then
           begin
                 S_phn:=P_simpul(Pd);
                 if Pd='(' then
                       push(Opr,S_phn)
                 else
                 if Pd=')' then
                 begin
                       while Opr^.item^.info <> '(' do
                             push(Opn,gabung);
                       pop(Opr,T1);
                  end
                  else
                  if Pd in Operator1 then
                  begin
                        while (Opr <> nil) and (valensi(Pd) <=
valensi(Opr^.item^.info)) do
                              push(Opn,gabung);
                              push(Opr,S_phn);
                  end
                  else
                  if Pd in Operand then
                        push(Opn,S_phn)
                  else
                  begin
                        betul:=false;
                        exit;
                  end;
                  gotoxy(23,wherey); cetak_stack(Opr);
                  gotoxy(45,wherey-1); cetak_stack(Opn);
            end
      end;
      writeln(Gr,Gr,Gr);
      while Opr <> nil do
      push(Opn,gabung);
      Pohon:=Opn^.item;
      dispose(Opn);
end;
procedure cetak_prefix(phn:tree);
begin
      if phn <> nil then
      begin
            write(phn^.info,' ');
            cetak_prefix(phn^.kiri);
            cetak_prefix(phn^.kanan);
      end;
end;
procedure cetak_infix(phn:tree);
begin
      if phn <> nil then
      begin
            cetak_infix(phn^.kiri);
            write(phn^.info,' ');
            cetak_infix(phn^.kanan);
      end;
end;
procedure cetak_postfix(phn:tree);
begin
      if phn <> nil then
      begin
            cetak_postfix(phn^.kiri);
            cetak_postfix(phn^.kanan);
            write(phn^.info,' ');
      end;
end;
BEGIN
        clrscr;
        lagi:='Y'; Gg:=chr(196);
        repeat
              tampilan;
              write('Masukkan ungkapan dalam notasi INFIX: ');
              readln(Infix); clrscr;
              write('Notasi Infix: ');
              for I:=1 to length(Infix) do
                    if Infix[I] <> ' ' then
                          write(upcase(Infix[I]),' ');
                    writeln; writeln;

              buat_pohon(pohon, betul, Infix);
              if betul then
              begin
                    writeln;
                    write('Notasi Prefix : ');
                    cetak_prefix(pohon); writeln; writeln;
                    write('Notasi Infix : ');
                    cetak_infix(pohon); writeln; writeln;
                    write('Notasi Postfix : ');
                    cetak_postfix(pohon); writeln; writeln;
              end
              else
              begin
                    write('<',chr(205),chr(205),chr(205));
                    writeln(chr(205),chr(184));
                    write(' ':15,chr(192),Gg,Gg,Gg);
                    write(' karakter tidak sah ');
                    writeln('("INVALID CHARACTER")');
                    writeln(Gr,Gr,Gr); writeln; writeln;
                    write('Maaf tidak bisa');
                    writeln('Teruskan lagi .....?');
              end;
              writeln;
              write('akan mencoba lagi ? [Y/T] : ');
              lagi:=upcase(readkey); clrscr;
        until lagi <> 'Y';

END.
                                    SORT (PENGURUTAN)

        Pengurutan data (sorting) , ada juga yang menyebutnya sebagai pemilahan data,
secara umum bisa didefinisikan sebagai suatu proses untuk menyusun kembali himpunan
obyek menggunakan aturan tertentu. Secara umum ada dua jenis pengurutan yaitu :
ascending dan descending. Jika data yang diurutkan bertipe char atau string maka nilai data
dikatakan lebih kecil atau lebih besar dari yang lain berdasarkan pada urutan relatif seperti
yang dinyatakan pada tabel ascii.
        Pengurutan menjadi suatu yang penting dalam struktur data atau ilmu komputer
secara umum karena waktu yang diperlukan untuk melakukan proses pengurutan perlu
dipertimbangkan.
        Data yang harus kita urutkan tentunya sangat bervariasi dalam hal banyaknya data
maupun jenis data yang akan diurutkan. Sayangnya tidak ada satupun algoritma yang
dikatakan terbaik untuk setiap situasi yang kita hadapi. Cukup sulit menentukan algoritma
yang paling baik untuk sebuah situasi tertentu karena ada beberapa faktor yang
mempengaruhi efektifitas algoritma pengurutan. Beberapa faktor yang mempengaruhi:
banyaknya data, kapasitas memori, tempat penyimpanan dsb.
        Keuntungan dari proses pengurutan data adalah : data mudah dicari, mudah
diperbaiki, dihapus, disisipi atau digabungkan. Dalam keadaan terurutkan dengan mudah
kita bisa mengecak kelangkapan data. Berikut ini macam-macam metode pengurutan
        A. PENGURUTAN LARIK
           Dalam pengurutan larik, yang mana data akan disimpan dalam pengingat utama
           komputer, ada aspek ekonomis yang harus dipertimbangkan. Ada beberapa
           metode yang dapat digunakan, straight method, selection method,
            sort method, shell sort method, quicksort method, radix sort dan merge sort.
           Namun kita tidak akan membahas keseluruhan.
           1. Straight method
               Proses pengurutan dengan metode penyisipan langsung dapat dijelaskan
               sebagai berikut: Data dicek satu per satu mulai dari yang kedua sampai
               dengan yang terakhir. Apabila ditemukan data yang lebih kecil daripada data
               sebelumnya, maka data tersebut disisipkan pada posisi yang sesuai. Akan
               lebih mudah apabila membayangkan pengurutan kartu. Pertama-tama anda
               meletakkan kartu-kartu tersebut di atas meja, kemudian melihatnya
               dari kiri ke kanan. Apabila kartu di sebelah kanan lebih kecil daripada kartu di
               sebelah kiri, maka ambil kartu tersebut dan sisipkan di tempat yang sesuai.


procedure tukar(var A,B:integer);
var T:integer;
begin
      T:=A;
      A:=B;
      B:=T;
end;
procedure sisip_langsung(var A:larik; N:Integer);
var I,J:integer; T:real;
begin
      for I:=2 to N do
      begin
            T:=A[I];
            J:=I-1;
            A[0]:=T;
            while T < A[J] do
            begin
                  A[J+1] :=A[J];
                  dec[J];
            end;
            A[J+1]:=T;
      end;
end;



        2. Selection method
           Jika anda diminta untuk membuat algoritma sorting tersendiri, anda mungkin
           akan menemukan sebuah algoritma yang mirip dengan selection sort.
           layaknya insertion sort, algoritma ini sangat rapat dan mudah untuk
           diimplementasikan.
           Mari kita kembali menelusuri bagaimana algoritma ini berfungsi terhadap
           satu paket kartu. Asumsikan bahwa kartu tersebut akan diurutkan secara
           ascending. Pada awalnya, kartu tersebut akan disusun secara linier pada
           sebuah meja dari kiri ke kanan, dan dari atas ke bawah. Pilih nilai kartu yang
           paling rendah, kemudian tukarkan posisi kartu ini dengan kartu yang terletak
           pada pojok kiri atas meja. Lalu cari kartu dengan nilai paling rendah diantara
           sisa kartu yang tersedia. Tukarkan kartu yang baru saja terpilih dengan kartu
           pada posisi kedua. Ulangi langkah – langkah tersebut hingga posisi kedua
           sebelum posisi terakhir dibandingkan dan dapat digeser dengan kartu yang
           bernilai lebih rendah.
           proses      Data[1]    Data[2]    Data[3]    Data[4]     Data[5]
           Awal        23         12         14         39          35
           I:1,        12         23         14         39          35
           I:2         12         14         23         39          35
           I:3         12         14         23         39          35
           I:4         12         14         23         35          35
           Selesai


procedure selection(var A:larik; N:integer);
var I,J,lok:integer;
begin
      for I:=1 to N-1 do
      begin
            lok:=I; {lokasi elemen terkecil}
              for J:=I+1 to N do
                    if A[lok] > A[J] then
                          lok:=J;
                    {menukar}
              tukar(A[I],A[lok]);
       end;
end;



          3. Bubble sort
             Metode bubble sort sering juga disebut dengan metode exchange sort,
             adalah metode yang mendasarkan pada penukaran 2 buah elemen untuk
             mencapai keadaan urut yang diinginkan. Metode ini mudah namun juga yang
             paling tidak efisien.

              proses     Data[1]    Data[2]    Data[3]   Data[4]     Data[5]
              Awal       23         12         14        39          35
              I:1, J:1   12         23         14        39          35
              J:2        12         14         23        39          35
              J:3        12         14         23        39          35
              J:4        12         14         23        35          39
              I:2,J:1    12         14         23        35          39
              J:2        12         14         23        35          39
              J:3        12         14         23        35          39
              J:4        12         14         23        35          39
              I:3,J:1    Diteruskan hingga I:4 meskipun data sudah terurut

procedure gelembung(var A:larik; N:Integer);
var I,J:integer;
begin
      for I:=1 to N-1 do
            for J:=1 to N-I do
                  if A[J]>A[J+1] then
                        tukar(A[J],A[J+1]);
end;

       B. PENGURUTAN SENARAI
          Setelah kita membicarakan pengurutan dengan larik, mari kita bahas dengan
          menggunakan senarai beranta. Kali ini kita akan menggunakan metode radixsort,
          quicksort dan mergesort. Senarai yang digunakan adalah senarai berantai tunggal
          tak berkepala.
          RADIXSORT
              Radix Sort merupakan salah satu algoritma Non-Comparasion Sort
          (pengurutan tanpa pembandingan). Proses ynang dilakukan dalam metode ini
          adalah mengklasifikasikan data sesuai dengan kategori terurut yang tertentu, dan
          tiap kategori dilakukan pengklasifikasian lagi, dan seterusnya sesuai kebutuhan,
          lalu subkategori-kategori tersebut digabungkan kembali. Secara harfiah Radix
dapat diartikan sebagai posisi dalam angka, karena metode ini pertamakalinya
mengurutkan nilai-nilai input berdasarkan radix pertamanya, lalu pengurutan
dilakukan berdasarkan radix keduanya, dan begitu seterusnya. Mudahnya jika
ada angka seperti ini: 9890, maka status dari keempat angka itu berbeda. 9 yang
pertama beda dengan 9 yang kedua pada posisi tiga. 9 pertama statusnya ribuan
dan 9 kedua adalah puluhan. Seperti inilah kita akan mengklasifikasikan data.
Dalam hal ini kita akan membuat perjanjian angka pertama disebut digit
signifikan terbesar (DSB), dan yang terakhir disebut digit signifikan terkecil (DSK).
Saat kita menyadari adanya perbedaan digit pada posisi yang sama, saat itulah
kita mengetahui bilangan mana yang lebih besar. Untuk lebih jelasnya mari kita
coba dengan data seperti berikut ini:
450, 345,432,549,120,229,257 (satuan)
 DATA                                  KELOMPOK
          0      1      2      3      4       5      6        7      8       9
450       450
345                                           345
432                     432
549                                                                          549
120       120
229                                                                          229
257                                                           257
HASIL 450,120,432,345,257,549,229

450,120,432,345,257,549,229 (puluhan)
 DATA                              KELOMPOK
        0      1     2       3     4    5             6       7      8       9
450                                     450
120                  120
432                          432
345                                345
257                                     257
549                                549
229                  229
HASIL 120,229,432,345,549,450,257

120,229,432,345,549,450,257 (ratusan)
 DATA                               KELOMPOK
        0      1     2       3     4     5            6       7      8       9
120            120
229                  229
432                                432
345                          345
549                                      549
450                                450
        257                  257
        HASIL   120,229,257,345,432,450,549


program radix_sort;
Uses Crt;
Type
Pointer = ^TypeData;
TypeData = Record
Nilai : integer;
Berikutnya : Pointer;
End;
Pointer2 = Array[0..9] Of Pointer;
Var
List : Pointer;
Q : Pointer2;
{====================================================================}
{===================== MASUK DATA DARI DEPAN ========================}
{====================================================================}
Procedure Masuk_Depan(Var L : Pointer; X : Integer);
Var
      Baru : Pointer;
Begin
      New(Baru);
      Baru^.Nilai := X;
      Baru^.Berikutnya := Nil;
      If L = Nil Then L := Baru
      Else
      Begin
            Baru^.Berikutnya := L;
            L :=Baru;
      End;
End;
{====================================================================}
{======================= PROCEDURE INITIALIZATION ===================}
{====================================================================}
Procedure Initial(Var Q : Pointer2);
Var
      i : byte;
Begin
      For i := 0 To 9 Do Q[i] := Nil;
End;
{====================================================================}
{=============== SUSUN DATA UNTUK TIAP MACAM DALAM ARRAY ============}
{====================================================================}
Procedure Susun(L : Pointer;Var Q1 : Pointer2);
Var
      Bantu,Baru : Pointer;
      i : Byte;
Begin
      Bantu := L;
      While Bantu <> Nil Do
      Begin
            New(Baru);
            Baru^.Berikutnya := Nil;
            Baru^.Nilai := Bantu^.Nilai;
            Masuk_Depan(Q1[Baru^.Nilai],Baru^.Nilai);
            Bantu := Bantu^.Berikutnya;
     End;
End;
{====================================================================}
{=================== PROCEDURE CONCATINATION DATA ===================}
{====================================================================}
Procedure Concatination(L : Pointer2; Var Q1 : Pointer);
Var
      Bantu,Baru : Pointer;
      i : Byte;
Begin
      For i := 0 To 9 Do
      Begin
            If L[i] <> Nil Then
            Begin
                  Baru := L[i];
                  If Q1 = Nil Then Q1 := Baru
                  Else
                  Begin
                        Bantu := Q1;
                        While Bantu^.Berikutnya <> Nil Do
                        Bantu := Bantu^.Berikutnya;
                  Bantu^.Berikutnya := Baru
                  End;
            End;
      End;
End;
{====================================================================}
{========================= PROCEDURE CETAK DATA =====================}
{====================================================================}
Procedure Cetak(L : Pointer);
Var
      Bantu : Pointer;
Begin
      Bantu := L;
      While Bantu <> Nil Do
      Begin
            Write(Bantu^.Nilai:3);
            Bantu := Bantu^.Berikutnya;
      End;
End;
{====================================================================}
{======================= PROCEDURE CETAK DATA =======================}
{====================================================================}
Procedure Cetak_Susunan(L : Pointer2);
Var
      Bantu,Baru : Pointer2;
      i : Byte;
Begin
      For i := 0 to 9 do
      Begin
            Write(' Q[',i,'] =');
            If L[i] <> Nil Then
            Begin
                  Bantu[i] := L[i];
                  While Bantu[i] <> Nil Do
                  Begin
                        Write(Bantu[i]^.Nilai:3);
                          Bantu[i] := Bantu[i]^.Berikutnya;
                  End;
           End;
           Writeln;
      End;
End;
{====================================================================}
{========================== PROGRAM UTAMA ===========================}
{====================================================================}
Var
      Bil,N : Byte;
Begin
      New(List);
      List:=Nil;
      Initial(Q);
      Randomize;
      Repeat
            Bil:=Random(10);
            Masuk_Depan(List,Bil);
            N:=N+1;
      Until N=20;
      Writeln;
      Writeln(' Mengurutkan Data Dengan Metode RADIX SORT');
      Writeln;
      Writeln(' DATA SEBELUM DIURUTKAN ....');
      Cetak(List);
      Writeln;
      Susun(List,Q);
      writeln;
      Writeln(' HASIL PENGELOMPOKAN ...');
      Cetak_Susunan(Q);
      Writeln;
      List:=Nil;
      Concatination(Q,List);
      Writeln(' HASIL PENGURUTAN SETELAH DIKELOMPOKKAN');
      Cetak(List);
      writeln;
End.

        QUICK SORT

        Metode ini diperkenalkan oleh C.A.R hoare. Untuk mempertinggi efektifitasnya
        dalam metoda jarak ini kedua elemen yang akan ditukar nilainya ditentukkan
        cukup besar.

        Merupakan proses penyusunan elemen yang membandingkan suatu elemen
        (pivot) denan elemen yang lain, dan menyusunnya sedemikian rupa sehingga
        elemen –elemen lain yang lebih kecil dari pivot terletak disebelah kiri pivot. Dan
        elemen yang lebih besar dari pivot terletak disebelah kanan pivot. Dengan
        demikian akan terbentuk dua sublist, yang terletak disebelah kanan dan kiri
        pivot. Lalu pada sublist kiri dan kanan itu kita anggap sebuah list baru, dan kita
        kerjakan proses yang sama seperti yang sebelumnya. Demikian seterusnya
        sampai tidak terdapat sublist lagi.
         Mari kita contohkan urutan data berikut ini:
         29-38-12-54-32-28-18-19-36
         Kita jadikan 29 sebagai pivot point
         12-28-18-19- (29) -38-54-32-36
         (12) -28-18-19 (29) -32-36- (38) -54
         (12) -18-19- (28) (29) (32) -36- (38) -54
         (12) (18)-19(28)(29)(32)-36-(38)-54


{
    procedure mengurutkan data dengan quicksort linked list
    dengan cara rekursif.
    P1 adalah pointer yang menunjuk ke senarai sebelum diurutkan
    P2 adalah pointer yang menunjuk ke senarai setelah diurutkan
    akhir adalah pointer yang menunjuk node terakhir
}

program quicksort;

uses crt;
var i : byte;
procedure sambung(B:list; var S,S1:list);
begin
      if S=nil then
            S:=B
      else
            S1^.kanan:=B;
      S1;=B
end;
procedure sortquick(var p2:list; p1:list);
var bwhd,bwhb,tengd,tengb,atd,atb:list;
begin
      if p1=nil then
      {masih kosong}
      begin
            akhir:=nil;
            p2:=p1;
      end
      else
      {proses senarai}
      begin
            bwhd:=nil;
            tengd:=nil;
            atd:=nil;
            sambung(p1,tengd,bwhb);
            p1:=p1^.kanan;
            while p1<>nil do
            begin
                  if p1^.info < tengd^.info then
                        sambung(p1,bwhd,bwhb)
                  else
                  if p1^.info = tengd^.info then
                        sambung(p1,tengd,tengb)
                  else
                        sambung(p1,atd,atb);
                     p1:=p1^.kanan
               end;
               if bwhd <> nil then
               begin
                     bwhb^.kanan:=nil;
                     sortquick(p2,bwhd);
                     akhir^.kanan:=tengd;
               end
               else
                     p2:=tengd;
               if atd <> nil then
                     atb^.kanan:=nil;
               sortquick(tengb^.kanan,atd);
               if akhir <> nil then
                     akhir:=tengb
        end;
end;
BEGIN
        {silakan isi sendiri}

END.

          MERGESORT

          Secara garis besar metode ini terbagi menjadi 2 cara pengerjaan. Mari kita
          perhatikan contoh data dibawah ini:

          12      35      9       11       3     17      23      15      31       20

          Dari data diatas yang hanya sebuah vektor lurus akan kita buat seakan-akan
          menjadi 3 vektor yang berbeda. Kita harus berhati-hati dalam memisahkan
          mereka. Misal kita sebut vektor pertama adalah 1 sampai batas dan vektor kedua
          adalah batas +1 sampai N. Dimana N adalah banyaknya data. Pemecahannya
          akan terus dilakukan hingga N Div 2.
          Cara pertama adalah kita mengurutkan data pada masing-masing vektor dan
          kemudian hasil akhirnya kita gabungkan.

          3       9       11      12       35    15      15      20      23       31


          Dan cara yang kedua disebut two ways mergesort method atau merge sort 2 arah.
          Penggambarannya adalah seperti berikut ini:
          Sebuah vektor lurus kita div 2 hingga ditemukan N div 2 = 0. Kemudia masing-
          masing tetangga dekat akan di cek dan ditukarkan. Seperti gambar berikut ini:

          12      35      9       11       3     17      15      23      20       31

          9       11      12      35       3     15      17      23      20       31

          3       9       11      12       15    17      23      35      20       31

          3       9       11      12       15    17      20      23      31       35
                                   SEARCH (PENCARIAN)
         Dalam kehidupan sehari-hari sebenarnya kita sering melakukan pencarian data.
Sebagai contoh, jika kita menggunakan Kamus untuk mencari kata-kata dalam Bahasa
Inggris yang belum diketahui terjemahannya dalam Bahasa Indonesia. Contoh lain saat kita
menggunakan buku telepon untuk mencari nomor telepon teman atau kenalan dan masih
banyak contoh yang lain.
         Pencarian data sering juga disebut table look-up atau storage and retrieval
information adalah suatu proses untuk mengumpulkan sejumlah informasi di dalam
pengingat komputer dan kemudian mencari kembali informasi yang diperlukan secepat
mungkin.
         Algoritma pencarian (searching algorithm) adalah algoritma yang menerima sebuah
argumen kunci dan dengan langkah-langkah tertentu akan mencari rekaman dengan kunci
tersebut. Setelah proses pencarian dilaksanakan, akan diperoleh salah satu dari dua
kemungkinan, yaitu data yang dicari ditemukan (successful) atau tidak ditemukan
(unsuccessful). Pencarian yang berhasil menemukan rekaman disebut dengan retrieval. Jika
data yang dicari tidak ditemukan dan kemudian ditambahkan dibelakang sebagai data baru
hal ini disebut algorima pencarian dan peyisipan (searching and inserting algorithm).

A. PENCARIAN BERURUTAN (sequential searching)

       Pencarian berurutan sering disebut pencarian linear merupakan metode pencarian yang
   paling sederhana. Pencarian berurutan menggunakan prinsip sebagai berikut : data yang ada
   dibandingkan satu per satu secara berurutan dengan yang dicari sampai data tersebut
   ditemukan atau tidak ditemukan. Pada dasarnya, pencarian ini hanya melakukan pengulangan
   dari 1 sampai dengan jumlah data. Pada setiap pengulangan, dibandingkan data ke-i dengan
   yang dicari. Apabila sama, berarti data telah ditemukan. Sebaliknya apabila sampai akhir
   pengulangan tidak ada data yang sama, berarti data tidak ada. Pada kasus yang paling buruk,
   untuk N elemen data harus dilakukan pencarian sebanyak N kali pula.
       Jenis pencarian ini hanya bagus untuk data yang acak atau tidak berurutan. Sedangkan untuk
   data yang sudah urut metode ini akan sangat buruk.
       Perhatikan algoritma dibawah ini:
       1. Baca vektor diketahui, sebanyak N elemen
       2. Baca data yang akan dicari
       3. Tentukan ketemu = false
       4. I = 1 sampai N kerjakan langkah 5
       5. Tes apakah data dicari = data[I]?
          Jika ya maka ketemu = true dan posisi =I
      6. Tes apakah ketemu = false
         Jika ya maka tingkatkan batas N dan data[N] = data dicari
      7. selesai

program searching;

var
   data : array [1..10] of integer;
   i : integer;
   jumlahdata: integer;
   keyword : integer;
   ketemu : boolean;
   posisi : integer;

begin
   write('Masukkan jumlah data : ');
   readln(jumlahdata);
   writeln;

   for i := 1 to jumlahdata do
   begin
         write('Masukkan angka ke-', i, ' : ');
         readln(data[i]);
   end;

   write('Masukkan angka yang akan dicari : ');
   readln(keyword);

   ketemu := false;
   i := 1;
   while (not ketemu) and (i<jumlahdata) do
   begin
         if(data[i] = keyword) then
         begin
          ketemu := true;
          posisi := i;
         end;
     i := i + 1;
   end;

   if(ketemu) then
   begin
     writeln('Data yang anda cari : ', keyword, ' berada pada posisi ke
: ', posisi);
   end
   else
   begin
     writeln('Data yang anda cari : ', keyword, ' tidak ditemukan');
   end;

end.

program searching;
uses crt;
type larik=array[1..100]of char;
var I,jumdata,posisi:integer;
data,cari:char;
isian:larik;
ketemu:boolean;

BEGIN
        clrscr;
        gotoxy(15,1); writeln('PROGRAM PENCARIAN LINIER');
        gotoxy(15,2); writeln('========================');
        writeln;
        write('Berapa jumlah huruf yang akan diisikan: ');
        readln(jumdata);
        writeln;
        for I:=1 to jumdata do
            begin
                    write('Masukkan Huruf ke-',I,' : ');
                    readln(isian[i]);
            end;
      writeln('======================================');
      write('Huruf apa yang anda cari :');
      readln(cari);
      ketemu:=false;
      I:=1;
      while (ketemu =false) and (I<jumdata) do
      begin
            if (isian[I] = cari) then
            begin
                  ketemu:=true;
                  posisi:=I;
            end;
            I:=I+1;
      end;
      if (ketemu) then
      begin
             writeln('Huruf yang anda cari : ', cari, ' berada pada
posisi ke : ', posisi);
      end
      else
      begin
             writeln('Huruf yang anda cari : ', cari, ' belum ada,
segera ditambahkan');
             inc(jumdata);
             isian[jumdata]:=cari;
      end;
      writeln('Urutan Huruf teranyar adalah:');
      for I:=1 to jumdata do
      begin
            write(isian[I],' - ');
      end;
      writeln;
END.

         Untuk implementasi dengan senarai berantai, maka yang kita perlukan adalah
   single linked list, karena pencarian yang kita lakukan bersifat linier.

program HCSLL;
uses crt;
type pointer=^DataNilai;
        DataNilai=record
                nilaihrf : char;
                next : pointer;
                end;

var head: pointer;
      x,pil:char;

procedure kondisiawal(var head:pointer);
begin
new(head);
      head^.next:=head;
end;
procedure addfront(var head:pointer; x:char);
var baru,bantu:pointer;
begin
      new(baru);
      baru^.nilaihrf:=x;

     if head^.next = head then {senarai kosong}
           begin
                 baru^.next:=head;
                 head^.next:=baru;
           end
           else
           begin
                 bantu:=head;
                 baru^.next:=bantu^.next;
                 head^.next:=baru;
                 bantu:=baru;
           end;
end;
procedure addback(var head:pointer; x:char);
var baru,bantu:pointer;
begin
      new(baru);
      baru^.nilaihrf:=x;

     if head^.next = head then {senarai kosong}
           begin
                 baru^.next:=head;
                 head^.next:=baru;
           end
           else
           begin
                 bantu:=head;
                 while (bantu^.next <> head) do
                       bantu:=bantu^.next;
                 baru^.next:=head;
                 bantu^.next:=baru;
           end;
end;
procedure readnodes(var head:pointer);
var bantu:pointer;
begin
      bantu:=head;
      repeat
            bantu:=bantu^.next;
            write(bantu^.nilaihrf:2);
      until bantu^.next=head;
      writeln;
end;
procedure searchnodes(var head:pointer;x:char);
var bantu:pointer;
posisi,I:integer;
ketemu:boolean;
begin
      bantu:=head;
      ketemu:=false;
      I:=1;
      while (ketemu=false) and (bantu^.next <> head) do
       begin
               bantu:=bantu^.next;
               if (bantu^.nilaihrf = x) then
               begin
                     ketemu:=true;
                     posisi:=I;
               end;
               I:=I+1;
      end;
      if (ketemu) then
      begin
             writeln('Huruf yang anda cari : ', x, ' berada pada posisi
ke : ', posisi);
      end
      else
      begin
             writeln('Huruf yang anda cari : ', x, ' belum ada, segera
ditambahkan');
             addback(head,x);
      end;
end;
BEGIN
clrscr;
kondisiawal(head);
repeat
writeln('Choose one menu to do :');
writeln('1. Add Nodes');
writeln('2. Print Nodes');
writeln('3. Search Nodes');
writeln('4. Exit');
writeln;
write('Pick One in [1/2/3] :'); readln(pil);
case pil of
      '1':begin
                  writeln('Add Data From The back Side'); writeln;
                  write('Type a char value :');readln(x);
                  addback(head,x);
            end;
      '2':begin
                  writeln('Print The Node List');writeln;
                  readnodes(head);
            end;
      '3':begin
                  writeln('Search Data :');
                  write('What Character you want to find : ');
                  readln(x);
                  searchnodes(head,x);
            end;
      '4':writeln('SEE YOU');
end
until pil ='3';

END.

B. PENCARIAN PADA DATA YANG SUDAH URUT
   Pada data yang sudah urut proses pencariannnya akan sedikit berbeda untuk
   mengefisienkannnya. Secara singkat proses pencariannnya adalah sebagai beriikut :
   1. Mulai dari data pada elemen pertama tes apakah data dicari lebih besar (jika urut
      ascending), kemudian pencarian diteruskan.
   2. Namun jika ditemukan data pada vektor lebih besar dan tidak sama dengan data
      dicari maka sudah pasti data tidak temukan.
   3. Pencarian berhenti.

        Untuk implementasinya silakan modifikasi program double linked list pada materi
        sebelumnya.

C. BINARY SEARCHING

      Pencarian Biner (Bah.Ingg: Binary Search) adalah pencarian data secara eliminasi
   biner berulang/terus-menerus. Maksudnya adalah pada saat pencarian data, 1
   kelompok data yang sudah urut dibagi menjadi 2 subkelompok. Lalu salah satu
   subkelompok dieliminasi, sehingga ruang lingkup pencarian data menjadi lebih sedikit.
   Kemudian subkelompok yang tersisa dibagi lagi menjadi 2 subkelompok lagi, demikian
   dilakukan secara berulang-ulang. Untuk pencarian biner perlu dicamkan bahwa:
  1. Pencarian hanya bisa dilakukan pada data yang sudah urut.
  2. Merupakan salah satu contoh penerapan konsep divide and conquer.

   untuk lebih menjelaskan keadaan diatas mari kita buat contoh seperti berikut ini;

   2           6         8          9           12          16        18          19

   Data dari satu vektor akan di ubah menjadi dua vektor:

   2           6         8          9           12          16        18          19

   Misal data dicari adalah 16. Maka cek di data maks vektor pertama, jika yang dicari
   lebih besar maka abaikan vektor pertama. Langsung ke vektor kedua.
   Bagi 2 vektor kedua menjadi

   12          16         18            19

   Kemudian cek pada data maks vektor kiri/ pertama, jika sama atau data dicari lebih kecil
   maka data pasti di vektor tersebut.
   Hal ini akan sangat menghemat waktu daripada harus mencari kesemua tempat. Untuk
   implementasinya :

Program BinarySearch;
Uses Crt;
Type
     Arraykoe = Array[1..10] of Integer;
Var
   A         : Arraykoe;
   i, j      : Integer;
   N1, X1, IX1 : Integer;

Procedure CariBinarySearch(L:Arraykoe; N : Integer; Var IX:Integer);
Var
   Ia, Ib : Integer;
   K       : Integer;
   ketemu : Boolean;
Begin
     Ia:=1;
     Ib:=N;
     ketemu:=false;
     while (not ketemu) and (Ia<=Ib) do
     Begin
           k:=(Ia+Ib)div 2;
           if (L[k]=IX) then
              ketemu:=true
           else
           If (L[k] < IX) then
              I:=k+1
           else
                Ib:=k-1;
     End;
     If (ketemu) then

          Writeln('Ketemu di :',k)
       else
           Writeln('Tidak Ketemu');
End;

Begin
     Clrscr;
     Write('Berapa Data : ');Readln(N1);
     For i:=1 to N1 do
     Begin
           Write('Data ke-',i,' : ');Readln(A[i]);
     end;
     Write('Masukkan Data yang dicari : ');Readln(IX1);
     CariBinarySearch(A,N1,IX1);
     Readln;
End.


D.

				
DOCUMENT INFO
Shared By:
Stats:
views:4461
posted:6/8/2011
language:Indonesian
pages:97