• Tidak ada hasil yang ditemukan

Bagi dua elemen larik pada elemen tengah Elemen tengah adalah elemen dengan indeks

Dalam dokumen Algoritma dan Struktur Data 2 (Halaman 46-54)

SORTING (PENGURUTAN) INTERNAL

Langkah 1 Bagi dua elemen larik pada elemen tengah Elemen tengah adalah elemen dengan indeks

k= (a + b) div 2. Elemen tengah, L[k], membagi larik menjadi dua bagian, yaitu bagian kiri L[ia..k-1] dan bagian kanan L[k+1..ib].

Langkah 2 : Periksa apakah L[k] = X (X adalah elemen yang dicari dalam larik). Jika L[k] = X, pencarian dihentikan karena X ditemukan. Jika L[k] <> X , harus ditentukan apakah pencarian akan dilakukan pada larik bagian kiri atau bagian kanan. Jika L[k] < X, maka pencarian dilakukan pada larik bagian kiri. Sebaliknya, jika L[k] > X, pencarian dilakukan pada larik bagian kanan.

Langkah 3 : Ulangi langkah 1 sampai X ditemukan atau ia > ib yaitu ukuran larik sudah nol.

Contoh pencarian biner :

Misalakan diberikan larik L, dengan 8 elemen yang sudah terurut descending seperi berikut : Procedure cari runtun_ascaending(a:larik, var ada:boolean;var n:integer; var posisi:integer; data :integer); {elemen vektor bertipe integer. Jika data yang dicari ditemukan, letaknya disimpan sebagai peubah posisi. Jika tidak ditemukan, data baru tersebut akan disisipkan ke dalam vektor}

Var i, j : integer; {indeks untuk pencarian} Begin

i := 1; j:=0; ada := false; repeat

if a[i] = data then {elemen yang dicari ditemukan}

begin

posisi := i; ada := true;

end

else if a[i] > data then {elemen yang dicari tidak ditemukan}

begin

j := i; {posisi elemen yang baru}

i := N-1;

end;

inc(i); until (i = n) or ada;

if not ada then {data tidak ketemu} begin

if j = 0 then {elemen baru menempati subkrib terakhir} a [n+1] := data;

else {menyisip di tengah}

begin

for i := n downto j do {menggeser elemen}

a[i+1] := a[i];

a[j] := data; {menempatkan elemen baru}

end;

inc (n); {menambah ukuran vektor}

end; End;

94 67 55 44 42 18 12 06

ia=1 2 3 4 5 6 7 ib=8

(i) Misalkan elemen yang di cari adalah X = 44. Langkah 1 :

ia = 1 dan ib = 8.

Indeks elemen tengah k = (1 + 8) div 2 = 4 (diarsir)

94 67 55 44 42 18 12 06 1 2 3 4 5 6 7 8

Langkah 2 :

L[4] = 44 ? Ya. (X ditemukan, pencarian dihentikan).

(ii) Misalkan elemen yang di cari adalah X = 42.

Langkah 1 : ia = 1 dan ib = 8.

Indeks elemen tengah k = (1 + 8) div 2 = 4 (diarsir)

94 67 55 44 42 18 12 06

ia=1 2 3 4 5 6 7 ib=8

Langkah 2 :

L[4] = 42 ? Tidak. Harus diputuskan apakah pencarian akan dilakukan di bagian kiri atau bagian kanan dengan pemeriksaan sbb :

L[4] > 42? Ya. Lakukan pencarian pada larik bagian kanan dengan ia = k + 1 = 4 +1 = 5 dan ib = 8 (tetap)

42 18 12 06 ia=5 6 7 ib=8 Langkah 1’ :

ia = 5 dan ib = 8.

Indeks elemen tengah k = (5 + 8) div 2 = 6 (diarsir)

42 18 12 06

5 6 7 8 Langkah 2’ :

L[6] = 42 ? Tidak. Harus diputuskan apakah pencarian akan dilakukan di bagian kiri atau bagian kanan dengan pemeriksaan sbb :

L[6] > 42? Tidak. Lakukan pencarian pada larik bagian kiri dengan ia = 5 (tetap) dan ib = k - 1 = 6 –1 = 5 42 5 kiri kanan kiri kanan Kiri’ Kanan’ :

Langkah 1’’ : ia = 5 dan ib= 5

Indeks elemen tengah k = (5 + 5) div 2 =5 (diarsir) 42

5

Langkah 2’’

L[5] = 42 ? Ya. (X ditemukan, pencarian dihentikan)

(iii) Misalkan elemen yang di cari adalah X = 97.

Langkah 1 : ia = 1 dan ib = 8.

Indeks elemen tengah k = (1 + 8) div 2 = 4 (diarsir)

94 67 55 44 42 18 12 06

ia=1 2 3 4 5 6 7 ib=8

Langkah 2 :

L[4] = 97 ? Tidak. Harus diputuskan apakah pencarian akan dilakukan di bagian kiri atau bagian kanan dengan pemeriksaan sbb :

L[4] > 97? Tidak. Lakukan pencarian pada larik bagian kiri dengan ia = 1 (tetap) dan ib = k – 1 = 4 – 1= 3

94 67 55 ia=1 2 ib=3 Langkah 1’ :

ia = 1 dan ib = 3.

Indeks elemen tengah k = (1 +3) div 2 = 2 (diarsir)

94 67 55

1 2 3

Langkah 2’ :

L[2] = 97 ? Tidak. Harus diputuskan apakah pencarian akan dilakukan di bagian kiri atau bagian kanan dengan pemeriksaan sbb :

L[2] > 97? Tidak. Lakukan pencarian pada larik bagian kiri dengan ia = 1 (tetap) dan ib = k - 1 = 2 –1 = 1 94 1 Langkah 1’’ : ia = 1 dan ib= 1 : kanan kiri Kiri’ Kanan’ :

Indeks elemen tengah k = (1 + 1) div 2 =1 (diarsir) 94

1 Langkah 2’’ ::

L[1] = 97 ? Tidak. Harus diputuskan apakah pencarian akan dilakukan di bagian kiri atau bagian kanan dengan pemeriksaan sbb :

L[1] > 97? Tidak. Lakukan pencarian pada larik bagian kiri dengan ia = 1 (tetap) dan ib = k - 1 = 1 – 1 = 0

karena ia > ib, maka tidak ada lagi bagian larik yang tersisa. Jadi, X tidak ditemukan di dalam larik , pencarian dihentikan.

Algoritma pencarian bagidua (biner)

Untuk pencarian biner pada larik yang sudah terurut menaik, hanya perlu mengganti If (L[k] > X ) then

dengan

If (L[k] < X ) then Untuk larik berukuran N elemen

- algoritma pencarian beruntun melakukan pembandingan elemen larik sebanyak N kali. - algoritma pencarian biner melakukan pembandingan elemen larik sebanyak 2log(N) kali.

Karena 2log(N) < N untuk N yang besar, maka algoritma pencarian biner lebih cepat daripada algoritma beruntun.

:

Procedure cari binerdescending(L:larik, n:integer; x:integer; var idxX:integer);

{mencari X di dalam larik L[1..N] yang sudah terurut menaik dengan metode pencarian biner. Keluaran dari proses ini adalah indeks idxX dimana L[idxX] :=X. idxX berharga 0 jika X tidak ditemukan} Var ia, ib, k : integer;

ketemu : boolean; Begin

ia := 1;

ib := N;

ketemu := false;

while (not ketemu) and (ia <= ib) do begin

k := (ia + ib) div 2; {bagidua larik L pada posisi k} if (L[k] = X) then

ketemu : = true

else {L[k] ≠X}

if (L[k] > X) then

{akan dilakukan pencarian pada larik begian kanan, set indeks ujung kiri larik yang baru} ia : = k + 1

else

ib : = k – 1; end;

{ketemu = true or ia > ib}

if (ketemu) then {X ditemukan} idxX := k

else {X tidak ditemukan di dalam larik} idxX := 0;

BAB VI

RECURSIVE

- Rekursif adalah proses pemanggilan dirinya sendiri (fungsi atau prosedur).

- Fungsi maupun prosedur yang memanggil dirinya disebut fungsi atau prosedur rekursif.

- Fungsi antuk suatu bagian program yang mengembalikan (menghasilkan) hanya satu nilai. Sebuah function call adalah suatu ekspresi jadi ia memberikan satu nilai.

- Procedure adalah suatu bagian program yang melakukan aksi/fungsi khusus, biasanya berdasarkan sekumpulan parameter. Sebuah procedure call adalah suatu statemen, jadi ia melakukan aksi. - Banyak obyek dalam matematika didefinisikan dengan menampilkan suatu proses untuk

menghasilkan obyek-obyek tsb.

- Misalnya : n faktorial (n!)didefinisikan sebagai produk dari semua integer diantara n dan 1. - Contoh lain adalah bilangan asli.

1 adalah bilangan asli.

Successor dari 1 adalah bilangan asli.

- Perbedaan rekursi dengan prosedur/fungsi adalah rekursi bisa memanggil kedirinya sendiri tetapi prosedur atau fungsi harus dipanggil lewat pemanggil prosedur/fungsi.

- Ciri masalah yang dapat diselesaikan secara rekursif adalah masalah tersebut dapat direduksi menjadi satu atau lebih masalah-masalah serupa yang lebih kecil.

- Secara umum suatu algoritma rekursif selalu mengandung 2 macam kasus :

1. satu atau lebih kasus yang pemecahan masalahnya dilakukan dengan menyelesaikan masalah serupa yg lebih sederhana (menggunakan recursive call).

2. satu atau lebih kasus pemecahan masalahnya dilakukan tanpa recursive call. Kasus ini disebut kasus dasar atau penyetop.

- Supaya tidak terjadi rekursif tak hingga, maka setiap langkah rekursif haruslah mengarah ke kasus penyetop.

- Sistem komputer mengikuti jalannya program yang rekursif biasanya dengan menggunakan suatu struktur data yang disebut stack.

- Ketika eksekusi program sampai pada suatu rekursif call, ia menghentikan sementara komputasi yg sedang dilaksanakannya sekarang untuk melakukan recursive call tsb, agar ia dapat kembali ke keadaan semula setelah recursive call itu selesai , ia harus menyimpan informasi yang cukup. Informasi yg diperlukan disebut activation frame.

- Activation frame disimpan pada bagian memori yg diatur dalam benruk stack.

- Rekursif yang berlapis-lapis dapat menghabiskan memori yang mengakibatkan stack overflow. - Masalah yg mempunyai solusi rekursif juga mempunyai solusi iteratif(menggunakan loop).

- Versi iteratif seringkali lebih efisien daripada versi rekursif karena rekursif biasanya menggunakan memori yg lebih besar dan memerlukan waktu ekstra u/ penanganan stack of activation frame. Contoh 1 menghitung faktorial :

n ! = 1 jika n = 0 atau n=1

n ! = n * (n-1) * (n-2) *…* 1, jika n > 0 Algoritma untuk definisi secara iteratif :

x n hasil 1 while x > 0 do begin hasil hasil*x x x-1 endwhile Definisi diatas dapat juga dituliskan sbb : n ! = 1 jika n = 0 atau n=1

n ! = n * (n-1)! , jika n > 0

Algoritma untuk definisi secara rekursif: Faktorial(n)

If (n = 0) or (n = 1) then faktorial 1 Else faktorial faktorial (n-1)*n endif

endfaktorial

Jika dituliskan dalam bentuk fungsi secara rekursif : Uses Crt; Function faktorial(N:integer):integer; Begin If (N=0) or (N=1) then Faktorial := 1 Else Faktorial := N * Faktorial (N-1); End; Var N:byte; {Program Utama} Begin Clrscr;

Write(‘Berapa faktorial : ‘);Readln(N); Writeln(‘Faktorial = ‘,faktorial(N); Readln;

End.

Contoh pencarian nilai 5! secara rekursif : 5 ! = 5*4!

Scr rekursif 4! Dihitung kembali sebesar 4*3! sehingga : 5 ! = 5*4*3!

Scr rekursif 3! Dihitung kembali sebesar 3*2! sehingga : 5 ! = 5*4*3*2!

Scr rekursif 2! Dihitung kembali sebesar 2*1! sehingga : 5 ! = 5*4*3*2*1 = 120

Jika dituliskan dalam bentuk prosedur secara rekursif : Uses Crt;

Procedure faktorial(N:integer;var hasil : integer); Begin If (N=0) or (N=1) then hasil := 1 Else begin Hasil:=hasil*n; Faktorial (N-1,hasil); End; End; Var N,f:integer; {Program Utama}

Begin Clrscr;

Write(‘Berapa faktorial : ‘);Readln(N); Faktorial(n,f);

Writeln(‘Faktorial = ‘,f); Readln;

End.

Contoh 2 populer yang sering digunakan untuk menjelaskan proses rekursif adalah fungsi penjumlahan dengan mengggunakan sigma.

Perhatikan fungsi dibawah ini :

function Summation (num : integer) : integer; begin

if num = 1 then Summation := 1 else

Summation := Summation(num-1) + num; end;

Asumsikan fungsi diatas dipanggil seperti dibawah ini : a := Summation(3);

maka proses yang terjadi adalah :

- Summation (3) menjadi Summation (2) + 3 - Summation (2) menjadi Summation (1) + 2

- Pada saat num=1 proses berhenti dan summation bernilai sama dengan 1 - Summation(2) menjadi 1 + 2

- Summation(3) menjadi 3 + 3

BAB VIII

POINTER

Tipe data pointer digunakan pada pemrograman dinamis, artinya kebutuhan memori tergantung saat program dieksekusi. Berbeda dengan pemrograman yang menggunakan predefined-types sebelumnya, dimana kebutuhan memori ditetapkan saat pendefinisian tipe data sehingga bisa berakibat memori yang teralokasi tidak semuanya terpakai, seperti penggunaan array (larik). Pemrograman seperti ini dikenal sebagai pemrograman memori statis.

8.1 Pengertian Pointer

Lihat potongan program di bawah ini :

Type pointer : ^integer;

Var a : integer;

pa : pointer;

Begin

a : = 10;

pa^ : = a;

…..

Sebelum a diberi nilai, a ditempatkan oleh sistem ke suatu alamat memori tertentu. Demikian juga pointer pa, sebelum diberikan nilai, pa menunjuk kepada suatu tipe data integer tak tentu. Nilai a adalah suatu nilai yang terletak didalam jangkauan tipe integer, sedangkan nilai pa adalah alamat memori suatu variabel/pengenal dengan tipe integer (lihat gambar). Oleh karena itu untuk mengakses sebuah pointer untuk kasus diatas digunakan operator isi ^ (atap atau simpul).

8.2 Deklarasi Pointer

Type pengenal = ^simpul;

Simpul = tipe;

Contoh : type bil_bulat = ^integer; var i, j : bil_bulat;

Umumnya tipe berupa rekaman (struktur) record, misal deklarasi : Type str30 = string[30]; point = ^data; data = record nomer : integer; nama_peg : str30; alamat : str30; pekerjaan : str30; end;

Kemudian bentuk definisinya : var P1, P2 : point; a,b,c : str30;

Agar nampak bahwa P1 dan P2 bersifat dinamis terhadap kebutuhan memori, deklarasi di atas dimodifikasi sebagai berikut :

Type str30 = string[30]; point = ^data; a ??? 10100 20200 pa . ??? a 10 10100 20200 pa .

data = record

nomer : integer; nama_peg : str30; alamat : str30; pekerjaan : str30;

next : point; {elemen ini baru}

end;

Setelah pendefinisian, kemudian minta memori kepada sistem dengan perintah : new (P1); new (P2);

maka P1 dan P2 sekarang siap diakses. Di sini ada dua elemen yang perlu dibedakan. Pertama untuk isi data sedangkan komponen kedua untuk pointer yang menunjuk kepada elemen berikutnya. Karena P1 dan P2 dalam hal ini hanya masih berdiri sendiri, maka elemen kedua P1 dan P2 sesuai definisi masing- masing menunjuk ke NIL ( Not In List, tak ada elemen yang mengikuti).

8.3 Operasi pada Pointer

Setelah pengalokasian memori dilakukan, langkah kedua pemberian nilai. Misalkan data P1 diberikan inisialisasi seperti berikut :

P1^.nomer := 1; P1^.nama := ‘Hasanuddin’; P1^.alamat := ‘Jl.Hasanudin 17; P1^pekerjaan := ‘Pedagang’;

Ilustrasi :

Ada 2 operasi yang sering diterapkan : 1. Mengkopi pointer

Contoh : P2:=P1;

2. Mengkopi isi(data)

Dianggap bagian pertama tidak dilakukan, contoh ; P2^:=P1^;

Dalam dokumen Algoritma dan Struktur Data 2 (Halaman 46-54)

Dokumen terkait