Anda di halaman 1dari 201

ISBN:

BUKU AJAR
MATA KULIAH

STRUKTUR DATA

PENYUSUN: Drs. Wahyu Pujiyono, M.Kom.

NAMA PENERBIT
KATA PENGANTAR

Alhamdulillah, atas segala rahmat dan hidayah-Nya, buku ajar


untuk mata kuliah Struktur Data dapat hadir memenuhi kebutuhan
mahasiswa sebagai tuntunan belajar.
Buku ajar ini sudah mengalami perubahan dari diktat sebelumnya.
Buku ajar ini mengikuti RPM (Rencana Pembelajaran Mingguan) yang
telah di buat dalam kurikulum. Cara belajarnya mengikuti bab yang ada
sebagai contoh bab 1 di baca sebelum kuliah minggu pertama.
Buku ajar ini di sertai power point dan file pendukung untuk setiap
minggunya. Harapan nya mahasiswa akan lebih mudah memahami teori
ketika di dampingi dengan file berisi progam yang sesuai dengan
materinya. Beberapa bab juga ada animasi pendukungnya. Mahasiswa
dapat mempelajari teori beserta dengan animasi yang sesuai.
Buku ajar ini terintegrasi antara materi teori dan praktikum. Ini
mengingat dalam sks mata kuliah tidak dipisahkan antara materi dan
praktikum berbobot 3 sks. Dalam implementasi nya, teori di sampaikan
berbobot 2 sks sedangkan praktikum berbobot 1 sks. Mahasiswa perlu
mensiasati cara belajar nya karena bobot teori dan praktikum berbeda.
Setiap tugas yang ada di teori dan praktikum tentu membutuhkan waktu.
Untuk itu alokasi waktu dalam belajar pun perlu di alokasikan dengan
sebaik-baiknya.
Buku ajar ini baru dalam proses pengembangan. Untuk itu
masukan untuk perbaikan tentu sangat berharga. Kami menerima
masukan untuk perbaikan di masa mendatang. Semoga buku ajar ini
bermanfaat bagi semua pihak. aamiin

Yogyakarta, 17 Agustus 2019


Drs. Wahyu Pujiyono, M.Kom
DAFTAR ISI

KATA PENGANTAR .................................................................................................................... ii


DAFTAR ISI ................................................................................................................................... iii

BAB I PEMROGRAMAN C++ .................................................................................................. 1


A. PENDAHUALUAN .................................................................................................................... 1
B. FUNGSI DAN PARAMETER .......................................................................................... 1
C. ALOKASI MEMORI DINAMIS ..................................................................................... 6
D. ARRAY SATU DIMENSI ................................................................................................. 7
E. PENANGANAN PERKECUALIAN ................................................................................ 7
F. OPERATOR DELETE ...................................................................................................... 8
G. FUNGSI REKURSIF ......................................................................................................... 8
BAB II KELAS (CLASS) .............................................................................................................. 18
A. PENDAHULUAN ...................................................................................................................... 18
B. KELAS CURRENCY ....................................................................................................... 18
C. OPERATOR OVERLOADING ....................................................................................... 26
D. PENANGANAN PERKECUALIAN ....................................................................................... 29
E. ANGGOTA KELAS FRIEND DAN PROTECTED ........................................................ 31
BAB III ARRAY ............................................................................................................................ 35
A. PENDAHULUAN ..................................................................................................................... 35
B. TIPE DATA ABSTRAK ARRAY SATU DIMENSI STATIS ....................................... 35
C. TIPE DATA ABSTRAK ARRAY SATU DIMENSI DINAMIS ................................... 39
D. TIPE DATA ABSTRAK ARRAY DUA DIMENSI ........................................................ 45
BAB IV REPRESENTASI DATA ................................................................................................ 53
A. PENDAHULUAN ............................................................................................................. 53
B. REPRESENTASI DATA DIDASARKAN RUMUS ....................................................... 53
C. REPRESNTASI DATA LINKED .................................................................................... 58
D. PERLUASAN KELAS CHAIN : ECHAIN ..................................................................... 65
BAB IV STACK (TUMPUKAN) .................................................................................................. 74
A. PENDAHULUAN ..................................................................................................................... 74
B. IMPLEMENTASI DENGAN ARRAY ............................................................................ 74
C. APLIKASI STACK : PENGECEKAN TANDA KURUNG .......................................... 81
D. APLIASKI STACK : MENARA HANOI ........................................................................ 82
BAB VI ANTRIAN ........................................................................................................................... 86
A. PENDAHULUAN ..................................................................................................................... 86
B. ANTRIAN DENGAN MENGGUNAKAN ARRAY ....................................................... 87
C. ANTRIAN DENGAN MENGGUNAKAN LINK LIST ................................................. 93
D. APLIKASI ANTRIAN .............................................................................................................. 98
BAB VII ............................................................................................................................................. 115
A. PENDAHULUAN ..................................................................................................................... 115
B. PHON BINER BINER (BINARY TREE ) ....................................................................... 117
C. POHON BINER MIRING (SKEWED BINARY TREE) .............................................. 118
D. DEKLARASI POHON ...................................................................................................... 119
E. KUNJUNGAN PADA PHON BINER .............................................................................. 120
DAFTAR PUSATAKA .................................................................................................................. 134
SKENARIO PEMBELAJARAN MINGGU 1

Persiapan [20 menit]


01. Dosen membuka perkuliahan
02. Dosen menjelaskan keterkaitan mata kuliah Algoritma dan
Pemograman dengan Strukur Data
03. Dosen menjelaskan tata cara pembelajaran dalam mata kuliah Struktur
Data
04. Dosen menjelaskan komponen penilaian mata kuliah Struktur Data
05. Penandatanganan kontrak belajar

Pembentukan Kelompok Tugas [15 menit]


01. Dosen meminta mahasiswa untuk membentuk kelompok belajar
sekaligus kelompok tugas proyek

Kegiatan Kuliah [30 menit]


01. Dosen menjelaskan review mata kuliah Algoritma dan Pemograman
02. Dosen memberikan tugas kepada mahasiswa, mahasiswa diminta
untuk memilih salah satu tugas dan mengerjakan secara
berkelompok

Kegiatan Diskusi [35 menit]


01. Mahasiswa mengerjakan tugas secara berkelompok, mahasiswa
mempresentasikan hasil diskusi kelompoknya

Bab 1 Dasar Dasar Pemrogaman halaman 1


Bab I

Pemrograman C++
Tujuan Pembelajaran

1. mahasiswa memahami prinsip-prinsip dasar pemrograman menggunakan C++

2. mahasiswa dapat menerapkan fasilitas-fasilitas bahasa pemrograman C++

A. Pendahuluan
Untuk menyelesaikan permasalahan dalam kehidupan real dengan bantuan
komputer diperlukan :
a. struktur data

b. algoritma

c. dan program komputer.

Proses pengembangan program akan memerlukan :


a. representasi data dengan suatu cara yang efektif

b. mengembangkan langkah-langkah prosedur yang cocok (algoritma) yang


dapat diimplementasikan menjadi program komputer.
Untuk itu sebelum mempelajari struktur data dan metode perancangan algoritma,
diperlukan pemahaman mendasar tentang bahasa pemrograman C++ dalam hal ini.
Bab ini akan diberikan dasar-dasar pemrograman untuk keperluan tersebut.
B. Fungsi dan Parameter
1. Parameter Nilai
Perhatikan program berikut.
Program 1.1
1. #include<iostream.h>
2. int Abc(int a, int b, int c)
3. { return a+b+b*c+(a+b-c)/(a+b)+4; }
4.
5. void main(void)
6. {

Bab 1 Dasar Dasar Pemrogaman halaman 2


7. cout << Abc(2,3,4) << endl;
8. }

Dalam program di atas, a, b, dan c adalah parameter formal dari fungsi Abc
yang masing-masing bertipe integer. Jika dipanggil dengan menggunakan
pernyataan
:
z = Abc(2,x,y);
maka 2, x, dan y dinamakan parameter aktual yang berkaitan dengan a, b, dan c.
Ketika pernyataan di atas dieksekusi, a diberi nilai 2, b diberi nilai dari x, dan c
diberi nilai dari y. Jika ternyata x dan y bertipe float maka akan diberlakukan
konversi tipe antara x dan a, serta b dan y. Misalnya x bernilai 3.8 maka a akan
bernilai 3.
Pada waktu jalan (run time), nilai parameter aktual berkaitan terhadap
parameter formal disalin ke parameter formal sebelum fungsi dieksekusi.
Penyalinan ini dilakukan dengan menggunakan copy constructor untuk tipe data
dari parameter formal. Ketika fungsi selesai dieksekusi, destructor untuk tipe data
parameter formal menghapus nilai parameter formal. Bila fungsi selesai, nilai dari
parameter formal tidak disalin ke parameter aktual, sehingga tidak mengubah
parameter aktualnya.

2. Fungsi Template
Misalkan kita menginginkan fungsi lain menghitung ekspresi yang sama dari
program 1.1. di atas, namun semua parameternya bertipe float, maka program 1.2.
berikut ini adalah fungsi tersebut :
Program 1.2
1. #include<iostream.h>
2. float Abc(float a, float b, float c)
3. { return a+b+b*c+(a+b-c)/(a+b)+4; }
4. void main(void)
5. { cout << Abc(2,3,4) << endl; }

Bab 1 Dasar Dasar Pemrogaman halaman 3


Daripada menulis berulangkali fungsi-fungsi tersebut untuk berbagai macam
tipe data, lebih baik kita membuat fungsi generik yang tipe datanya ditentukan oleh
kompilator. Kode generik seperti ini ditulis dengan menggunakan pernyataan
template sebagaimana diperlihatkan pada program 1.3. berikut ini :
Program 1.3
1. #include<iostream.h>
2. template<class T>
3. T Abc(T a, T b, T c)
4. {
5. return a+b+b*c+(a+b-c)/(a+b)+4;
6. }
7.
8. void main(void)
9. {
10. cout << Abc(2,3,4) << endl;
11. }

Dari fungsi generik ini, kompilator akan mengganti int untuk T untuk
mengkonstruksikan program 1.1., dan akan mengganti float untuk T pada program
1.2.

3. Reference Parameter
Dengan menggunakan parameter nilai akan meningkatkan waktu
jalannya program (RUn-time cost) pada program 1.3. Ketika a, b, dan c adalah
parameter nilai, copy constructor untuk tipe T menyalin harga berkaitan dengan
parameter aktual ke dalam parameter formal. Pada waktu keluar dari fungsi,
destructor untuk tipe T dijalankan dan parameter formal a, b dan c dihapus.
Misalkan T adalah tipe data yang dibuat sendiri Matriks di mana copy
constructor menyalin semua entri dari matriks dan destructor menghapus entri
matriks satu demi satu. Jika Abc dieksekusi dengan setiap parameter aktual matriks
dengan 10000 elemen, maka dengan menyalin 3 parameter aktual a, b dan c akan
memerlukan 30000 operasi. Bila Abc selesai destructor Matriks akan

Bab 1 Dasar Dasar Pemrogaman halaman 4


dieksekusi untuk menghapus a, b dan c yang memerlukan 30000 operasi juga.
Program 1.4. di bawah ini menggunakan parameter reference. Jika Abc dieksekusi
oleh pernyataan Abc(x,y,z) dengan x, y, dan z tipe data yang sama, maka parameter
aktual terikat terhadap nama a, b, dan c. Selama eksekusi fungsi Abc berlangsung,
nama x, y dan z digunakan pada tempat a, b, dan c. Dengan demikian, tidak seperti
pada kasus parameter nilai, program ini tidak menyalin nilai parameter aktual pada
waktu eksekusi fungsi dan tidak mengeksekusi destructor tipe T ketika keluar dari
fungsi.

Program 1.4
1. #include<iostream.h>
2. template<class T>
3. T Abc(T& a, T& b, T& c)
4. {
5. return a+b+b*c+(a+b-c)/(a+b)+4;
6. }
7. void main(void)
8. {
9. int a = 2, b = 3, c = 4;
10. cout << Abc(a,b,c) << endl;
11. }

1. const Reference Parameter


C++ menyediakan mode lain untuk melewatkan parameter ke fungsi, yaitu
const reference. Mode ini menandakan parameter reference tidak diubah oleh
fungsi. Dengan demikian, nilai a, b, dan c tidak berubah. Program 1.5.
memperlihatkan penulisan kode dengan mode ini.
Program 1.5
1. #include<iostream.h>
2. template<class T>
3. T Abc(const T& a, const T& b, const T& c)
4. {
5. return a+b+b*c+(a+b-c)/(a+b)+4;
6. }
7.

Bab 1 Dasar Dasar Pemrogaman halaman 5


8. void main(void)
9. {
10. cout << Abc(2,3,4) << endl;
11. }

Program 1.6. di bawah ini menggunakan penulisan yang lebih umum


dibanding dengan program 1.5. di atas. Pada versi baru ini, setiap parameter formal
bisa berbeda tipenya dan menghasilkan tipe yang sama dengan parameter pertama
(sebagai contoh).
Program 1.6
1. #include<iostream.h>
2. template<class Ta, class Tb, class Tc>
3. Ta Abc(const Ta& a, const Tb& b, const Tc& c)
4. {
5. return a+b+b*c+(a+b-c)/(a+b)+4;
6. }
7.
8. void main(void)
9. {
10. cout << Abc(2,3,4) << endl;
11. }

1. Mengembalikan Nilai
Fungsi dapat mengembalikan suatu nilai, mengembalikan reference atau
mengembalikan const reference. Kita menentukan mengembalikan referensi dengan
menambah simbol & di awal tipe yang dikembalikan. Kepala fungsi :
T& X(int i, T& z)
mendefinisikan fungsi X yang membuatnya mengembalikan tipe referensi T,
sebagai contoh, mengembalikan z menggunakan pernyataan :
return z;
dengan demikian z tidak terpengaruh, oleh karena z merefer ke parameter aktual.

Bab 1 Dasar Dasar Pemrogaman halaman 6


C. Alokasi Memori Dinamis
Alokasi memori dinamis dikerjakan dengan menggunakan operator new.
Operator ini mengembalikan pointer ke memori yang teralokasi. Sebagai contoh,
untuk mengalokasikan memori secara dinamis ke integer (misal variabel y) ke suatu
pointer, kita mendeklarasikannya dengan menggunakan pernyataan :
int *y;
ketika program memerlukan menggunakan integer, memori teralokasi dengan
menggunakan pernyataan :
y = new int;
operator new mengalokasikan sejumlah memori untuk menangani integer, dan suatu
pointer ke memori ini dikembalikan dan disimpan dalam y. Variabel y merujuk
pointer ke integer dan *y merujuk ke integer. Untuk menyimpan suatu harga
integer, misalnya 100, kita menggunakan pernyataan :
*y = 100;
Dengan demikian, terdapat 3 langkah untuk mengoperasikan suatu pointer yang
menunjuk ke integer, yaitu :

1. Deklarasikan variabel y
2. Alokasikan memori
3. Berikan nilai ke *y
int *y = new int; // langkah 1 dan 2
*y = 100; // langkah 3

atau

atau

int *y = new int (100);

int *y;
y = new int (100);

Bab 1 Dasar Dasar Pemrogaman halaman 7


D. Array Satu Dimensi
Dalam suatu kasus, kadang diperlukan bekerja dengan array satu atau dua
dimensi yang tidak diketahui berapa banyak ukurannya pada saat dikompilasi.
Untuk itu diperlukan alokasi memori secara dinamis.
Untuk membuat array satu dimensi bertipe float x pada saat program
dieksekusi, kita harus mendeklarasikan x sebagai pointer ke float, kemudian
mengalokasikan sejumlah memori untuk array tersebut. Sebagai contoh, array
floating point dengan ukuran n dibuat sebagai berikut :
float *x = new float [n];
Operator new mengalokasikan memori untuk n buah bilangan floating point
dan mengembalikan pointer ke elemen pertama. Elemen array diberi alamat dengan
penulisan x[0], x[1], …, x[n-1].

E. Penanganan Perkecualian
Apa yang terjadi dengan pernyataan :
float *x = new float [n];
ketika dieksekusi komputer dan ternyata memori tidak tersedia untuk n bilangan
floating point ? Pada kasus ini, new tidak mungkin mengalokasikan sejumlah
memori yang diperlukan, dan perkecualian terjadi. Menggunakan kompilator
Borland C++ perkecualian ini akan ditangani menggunakan xalloc (ada pada
except.h) yaitu thrown oleh perintah new ketika perintah new tidak dapat
mengalokasikan cukup memori. Kita dapat mendeteksi kegagalan perintah new
dengan “menangkap” perkecualian menggunakan konstruksi try – catch :
float *x;
try { x = new float [n];
} catch (xalloc) {
cerr << “Out of Memory” << endl;;
exit(1);
}

Bab 1 Dasar Dasar Pemrogaman halaman 8


Blok dalam struktur catch akan dimasuki hanya bila perkecualian xalloc muncul dan
dieksekusi oleh blok try. Pernyataan exit(1) (fungsi ini didefinisikan pada stdlib.h)
akan menghentikan program. Jika kita tidak menemukan blok catch yang cocok,
program berhenti dengan pesan :
Abnormal program termination.

F. Operator Delete
Apabila kita menggunakan pernyataan new untuk mengalokasikan memori,
suatu saat bisa terjadi memori tersebut tidak lagi digunakan. Untuk membebaskan
memori kita gunakan perintah delete. Pernyataan :
delete y;
delete [ ]
x;
akan membebaskan memori yang dialokasikan oleh *y dan array satu dimensi x.

G. Fungsi Rekursif
Fungsi rekursif adalah function yang memanggil dirinya sendiri secara
langsung maupun tidak langsung melalui function yang lain. Setiap function
rekursif mengandung 2 hal :
a. kasus yang paling sederhana atau kasus basis. Di dalamnya akan
mengembalikan suatu nilai
b. langkah rekursi (RECURSIVe call), di mana masalah yang kompleks
dipecah menjadi masalah yang lebih sederhana. Langkah rekursif ini harus
mengarah ke kasus basis.

Sebagai contoh adalah program untuk mencari nilai dari n! dengan n bilangan
integer non negatif. n! didefinisikan sebagai : (iteratif)

n! = n*(n-1)*(n-2)* ... * 1

dengan 1!=1 dan 0!=1. Persoalan ini dapat diselesaikan dengan cara iteratif
menggunakan pernyataan for. Misalkan akan dicari n!

Bab 1 Dasar Dasar Pemrogaman halaman 9


faktorial = 1;
for (int i=1; i<= n; i++)
faktorial = faktorial *
i;

Definisi faktorial bisa ditulis dengan relasi : (rekursif)

n! = n * (n-1)!
yang ditulis sebagai

faktorial := n * faktorial(n-1);

Perhatikan evaluasi rekursif dari 4! di bawah ini.

operasi push harga akhir = 24


4!
4!

4*3! 4! = 4*6 = 24 dikembalikan


4*3!
3*2! 3! = 3*2 = 6 dikembalikan
3*2!
2*1! 2! = 2*1 = 2 dikembalikan
2*1!
1 1 dikembalikan
1 Operasi Pop
a) proses recursive call b) harga yang dikembalikan pada setiap recursive call

Program 1.7. Menghitung n! secara iteratif


1. #include <iostream.h>
2. int Factorial(int n)
3. {
4. int i, hasil = 1;
5. for (i=1; i<=n; i++)
6. hasil = hasil * i;
7. return hasil;
8. }
9. void main(void)
10. {
11. cout << "5! = " << Factorial(5) << endl;
12. }

Bab 1 Dasar Dasar Pemrogaman halaman 10


Pada kasus perulangan iteratif di atas, kita dapat menggunakan pernyataan
perulangan while atau do .. while sebagai ganti for (5). Nilai kumulatif perkalian
dimulai dari 1 (4) dan pernyataan kumulatif nilai perkalian menggunakan (6) [
Silahkan merujuk diktat Algoritma dan Pemrograman ]. Nilai hasil dikembalikan
sebagai hasil dari fungsi Factorial (7).
Untuk kasus perulangan rekursif, nilai awal dapat kita pandang sebagai kasus
basis yang nantinya akan mengembalikan suatu nilai (4). Sementara sifat
pengulangannya menggunakan pemanggilan dirinya sendiri (5). Tentu saja rumus
yang digunakan disesuaikan dengan kasus yang dihadapi.
Program 1.8. Menghitung n! secara rekursif
1. #include <iostream.h>
2. int Factorial(int n)
3. {
4. if (n <= 1) return 1; // kasus basis
5. else return n * Factorial(n - 1); // pemanggilan rekursif
6. }
7. void main(void)
8. { cout << "5! = " << Factorial(5) << endl; }

Output dari program di atas untuk n = 5 adalah


Faktorial 5 = 120

1. Fungsi Rekursif dua parameter : Perkalian Dua Buah Integer

Definisi iteratif untuk kasus perkalian dua buah integer adalah sebagai berikut :

Definisi :
(iteratif) a x b =
 a + a + ... + a (b kali), untuk b > 0
 (-a) + (-a) + ... + (-a) (b kali), untuk b < 0

Dalam definisi di atas dapat dilihat bahwa perulangan selalu dipertahankan bernilai
positif, terutama untuk kasus b yang negatif, yaitu dengan cara mengalihkan nilai
negatif ke a. Implementasi definisi tersebut menggunakan fungsi sebagai berikut :

Bab 1 Dasar Dasar Pemrogaman halaman 11


Program 1.9. Perkalian menggunakan penjumlahan secara iteratif
1. #include <iostream.h>
2. #include <math.h>
3.
4. int kali_iteratif(int a,int b)
5. {
6. int i, hasil = 0; // nilai awal
7. for (i=1; i<=abs(b); i++)
8. hasil = hasil+a;
9. if (b<0) return -hasil;
10. else return hasil;
11. }
12.
13. void main(void)
14. {
15. cout << "3x(-5) = " << kali_iteratif(3,-5) << endl;
16. }

Fungsi absolut (abs) digunakan untuk perulangan yang selalu positif (7).
Fungsi abs prototipe fungsinya berada pada math.h (2). Sementara bila b bernilai
negatif, kita bisa menggunakan nilai negatif dari perhitungan semula untuk b positif
(9). Dalam implementasi menggunakan fungsi rekursif, nilai awal pada kasus
iteratif digunakan sebagai kasus basis (penyetop). Sementara dua kasus yang ada
pada definisi iteratif digunakan dan dimodifikasi untuk kasus rekursif. Definisi
rekursif dari kasus perkalian dua integer adalah sebagai berikut :
Definisi :
(rekursif) a x b =
 0, untuk b = 0
 a + (a x (b-1)), untuk b > 0
 -a + (a x (b+1)), untuk b < 0

Implementasi dari definisi rekursif di atas adalah sebagai berikut :


Program 1.10. Perkalian menggunakan penjumlahan secara rekursif
1. #include <iostream.h>

Bab 1 Dasar Dasar Pemrogaman halaman 12


2.
3. int kali_rekursif(int a,int b)
4. {
5. if (b==0)
6. return 0; // kasus basis
7. else if (b>0)
8. return a + kali_rekursif(a,b-1); // pemanggilan rekursif
9. Else
10. return (-a) + kali_rekursif(a,b+1); // pemanggilan rekursif
11. }
12.
13. void main(void)
14. {
15. cout << "3x(-5) = " << kali_rekursif(3,-5) << endl;
16. }
Pada kasus rekursif yang pertama, nilai b positif. Untuk mengarah pada kasus
basis (b = 0) maka nilai b selalu dikurangi dengan 1 (8). Sementara untuk kasus
rekursif yang kedua (b < 0), untuk mengarah pada kasus basis (b = 0) nilai b
ditambah dengan 1 (10).

2. Dua kali pemanggilan rekursi : Bilangan Fibonaci

Pada kasus-kasus sebelumnya, kita belajar tentang rekursif dengan satu dan
dua parameter. Kasus berikut ini melibatkan dua kali pemanggilan rekursif setiap
kali proses rekursif dilakukan.

Definisi :
Bilangan Fibonaci adalah bilangan
berbentuk : 1, 1, 2, 3, 5, 8, 13, 21, ...
yaitu bilangan ke-n merupakan penjumlahan dari bilangan ke-(n-2)
dan bilangan ke-(n-1).
Bilangan fibonaci memang sejak awal sudah terdefinisi secara rekursif,
artinya suku ke-n baru bisa diketahui bila dua suku sebelumnya diketahui. Dengan
demikian implementasinya menjadi sederhana, yaitu mengikuti dari definisi di atas.

Bab 1 Dasar Dasar Pemrogaman halaman 13


Program 1.11. program fibonaci secara rekursif
1. #include <iostream.h>
2. int fibonaci(int n)
3. {
4. if ((n==1) || (n==2)) return 1; // kasus basis
5. else
6. return fibonaci(n-1) + fibonaci(n-2); // pemanggilan rekursif
7. }
8.
9. void main(void)
10. {
11. cout << "fibonaci suku ke-10 = " << fibonaci(10) << endl;
12. }

3. Macam-macam Metode Rekursi


Ada 3 macam rekursi yang lazim digunakan, yaitu :
1. rekursi menurun (going down recursion), artinya nilai dari parameter
berkurang mengarah ke kasus basis
2. rekursi menaik (going up recursion), artinya nilai dari parameter bertambah
mengarah ke kasus basis
3. rekursi dibagi separoh (two half recursion), artinya range atau jangkauan dari

parameternya dibagi menjadi dua bagian, setengah bagian pertama pada


pemanggilan pertama sedangkan setengah sisanya pada pemanggilan kedua.
Berikut ini adalah contoh kasus yang digunakan untuk menjelaskan ketiga

macam rekursi di atas. Kasus ini digunakan untuk menghitung nilai m2 + (m+1)2 +

… + n2. Implementasi juga menggunakan cara iteratif sebagai pembanding.

Program 1.12. Jumlah Kuadrat Iteratif menggunakan template


1. #include<iostream.h>
2. template<class T>
3. T Sum(T m, T n)
4. {
5. T tsum = 0;
6. for (int i = m; i <= n; i++)

Bab 1 Dasar Dasar Pemrogaman halaman 14


7. tsum += i*i;
8. return tsum;
9. }
10.
11. void main(void)
12. {
13. int a = 5, b = 10;
14. cout << Sum(a,b) << endl;
15. }

Di bawah ini diberikan program jumlah kuadrat dengan menggunakan cara


going down recursion.

Program 1.13. Jumlah Kuadrat rekursif GoingDownRecursion


menggunakan template
1. #include<iostream.h>
2. template<class T>
3. T Sum(T m, T n)
4. { Going Down
5. if (m>=n) Recursion
6. return n*n;
7. else
8. return Sum(m, n-1) + n*n;
9. }
10. void main(void)
11. {
12. int a = 5, b = 10;
13. cout << Sum(a,b) << endl;
14. }

Terlihat dalam pemanggilan rekursi, nilai n selalu dikurangi dengan 1 yang


mengarah pada kasus basis (m >= n). Pohon pemanggilan rekursinya adalah sebagai
berikut :

355
GDR(5,10)

225
GDR(5,9) +100

174 GDR(5,8) +81

110 +64
GDR(5,7)

GDR(5,6)
Bab 1 Dasar Dasar Pemrogaman halaman 15
Gambar 4.1. Pohon pemanggilan rekursi secara menurun

Implementasi rekursi dengan cara menaik (going up recursion) diberikan di bawah


ini.
Program 1.14. Jumlah Kuadrat rekursif GoingUpRecursion
menggunakan template
1. #include<iostream.h>
2.
3. template<class T>
4. T Sum(T m, T n)
5. { Going Up
Recursion
6. if (m>=n)
7. return m*m;
8. else
9. return Sum(m+1, n) + m*m;
10. }
11.
12. void main(void)
13. {
14. int a = 5, b = 10;
15. cout << Sum(a,b) << endl;
16. }

Terlihat bahwa nilai m selalu bertambah 1 mengarah ke kasus basis (m >= n) .

GUR(5,10) 355

25 +
GUR(6,10) 330

36+
GUR(7,10) 294

49+
GUR(8,10) 245

64+
GUR(9,10) 181

Bab 1 Dasar Dasar Pemrogaman halaman 16


Gambar 4.2. Pohon pemanggilan rekursi secara menaik

Pada kasus ketiga yaitu rekursi dibagi separoh, nilai di tengah dihitung dari
nilai tengah parameternya yaitu m + n dibagi 2. Oleh karena bisa terjadi nilai
setengahnya tidak selalu bulat, maka bisa diambil hanya nilai integernya saja.
Implementasi dari rekursi dibagi separoh disajikan berikut ini :

Program 1.15. Jumlah Kuadrat rekursif TwoHalf


menggunakan template
1. #include<iostream.h>
2. template<class T>
3. T Sum(T m, T n)
4. { int tengah;
5. if (m==n) return m*m;
6. else Two alf
H
7. { Recursion
8. tengah = (m+n) / 2;
9. return Sum(m, tengah) + Sum(tengah+1, n);
10. }
11. }
12. void main(void)
13. {
14. int a = 5, b = 10;
15. cout << Sum(a,b) << endl;
16. }

Kasus basisnya memang agak berbeda, yaitu m = n untuk lebih meyakinkan

bahwa nilai m2 akan diperoleh bila m = n (lebih eksplisit). Bila pada dua kasus
sebelumnya, pohon pemanggilan miring (ke kiri dan ke kanan) maka pohon

pemanggilan dengan cara rekursi dibagi separoh akan menjadi pohon yang seimbang
seperti berikut ini :

TH(5,10)

TH(5,7) TH(8,10)
TH(7,7) TH(10,10)
TH(5,6) TH(8,9)

TH(5,5) TH(6,6) TH(8,8) TH(9,9)

Gambar 4.3. Pohon pemanggilan rekursi dibagi separoh

Bab 1 Dasar Dasar Pemrogaman halaman 17


Latihan
1. Buatlah fungsi bilangan Fibonaci dengan cara iteratif.

2. Buatlah fungsi untuk mencetak bilangan 1 sampai 10 secara iteratif dan


rekursif (going up recursion, going down recursion, dan two half recursion).
3. Buatlah subprogram x pangkat n dengan cara rekursif menggunakan ketiga
cara rekursi
4. Dengan menggunakan kenyataan bahwa deret :

1, 3, 7, 15, 31, …
hasil jumlahnya mengikuti rumus :
L(n) = 2*L(n-1) +1
buatlah fungsi iteratif dan rekursif untuk menghitung jumlah deret tersebut.

Bab 1 Dasar Dasar Pemrogaman halaman 18


SKENARIO PEMBELAJARAN MINGGU 2

Persiapan di Rumah [50 menit]


01. Mahasiswa membuat ringkasan kuliah minggu sebelumnya
02. Mahasiswa mencatat teori Struct : Deklarasi, membuat variabel, cara
memasukkan data ke komponen Struct, dan mengakses data dari Struct
03. Membuat contoh dari langkah 02. Menjalankan programnya dengan
compiler online

Pendahuluan [40 menit]


01. Dosen membuka perkuliahan
02. Dosen menjelaskan pentingnya Struct
03. Dosen memberikan contoh Struct. Mahasiswa mengikuti contoh
tersebut dalam compiler
04. Mahasiswa diberi kesempatan membuat main fuctionnya

Kegiatan Diskusi [30 menit]


01. Mahasiswa berdiskusi dengan kelompok masing-masing, setiap
mahasiswa menjelaskan contoh Struct yang sudah disiapkan dari
rumah kepada teman- temannya dan mendemokan programnya
02. Setiap mahasiswa menilai presentasi temannya. Komponen
penilaian : 60% presentasi 40% demo program
03. Setiap mahasiswa memiliki dokumentasi penilaian dari 2 teman
kelompoknya

Persiapan Praktikum [10 menit]


01. Dosen menjelaskan tata cara praktikum
02. Mahasiswa diminta membaca modul 1 praktikum

Penutup [20 menit]


01. Dosen memberikan kesempatan untuk bertanya
02. Dosen memberikan rangkuman hari ini
03. Dosen menutup perkuliahan

Bab 1 Dasar Dasar Pemrogaman halaman 19


Bab II
Kelas (class)
Tujuan Pembelajaran

1. mahasiswa memahami prinsip-prinsip dasar konstruksi kelas

2. mahasiswa dapat membuat kelas berdasar pada spesifikasi yang ditentukan

A. Pendahuluan

Sebelum menggunakan kelas kita harus tahu struktur struct dalam bahasa C.
Struct adalah kumpulan tipe data bentukan yang berisi kumpulan deklarasi variabel
menjadi sebuah nama dalam kesatuan yang utuh.

Sebagai contoh sebuah titik dalam dua dimensi terdiri dari absis (sumbu x) dan
koordinat (sumbu y)bila kita mendeklarasikan variabel biasa:

int x;

int y;
variabel x dan y yang masing masing bertipe int bisa di artikan untuk
menampung bilangan integer secara umum, tidak terlihat makna nya sebagai
representasi. Untuk itu kita kumpulkan dalam sebuah struktur struct.

Bentuk umum dari struct adalah:

Struct namastruct {
Daftar deklarasi variabel;
}

Contoh kasus titik di atas dapat di buat struct berikut ini:


struct titik{
int x = 0;
int y = 0;
};

Bab 2 Kelas (class) halaman 20


Untuk mendeklarasikan titik A dan B sebagai variabel bertipe struct maka kita
deklarasikan sebagai berikut:

titik A,B;
Perhatikan progam di bawah ini:

Tanpa menggunakan struct Menggunakan struct

#include <iostream> #include <iostream>


#include <cmath> #include <cmath>

long kuadrat(int a){ long kuadrat(int a){


return a*a; return a*a;

} }

float jarak(int x1, int y1, int x2, int y2) { float jarak(int x1, int y1, int x2, int y2) {
return sqrt (kuadrat(x2-x1) + kuadrat(y2- return sqrt (kuadrat(x2-x1) + kuadrat(y2-
y1)); y1));
} }

struct titik{
int main() { int x = 0;
int y = 0;

int xA = 0; };

int yA = 0;
int xB = 3; int main() {

int yB = 4; titik A, B;

std::cout << "Hello World!\n"; std::cin >> B.x >> B.y;

std::cout << "Jarak titik = " << std::cout << "Hello World!\n";
jarak(xA,yA,xB,yB);
std::cout << "Jarak titik = " <<
} jarak(A.x,A.y,B.x,B.y);
}

Bab 2 Kelas (class) halaman 21


Perhatikan bagaimana mengubah deklarasi bilangan bertipe int xA, yA, xB,
dan yB menjadi struktur struct titik di tabel sebelah kanan menjadi:

struct titik{
int x = 0;
int y = 0;
};

Dan deklarasi variabel nya menjadi:

titik A,B;

bilangan 0 ada dalam deklarasi di gunakan sebagai nilai awal (inisialisasi


variabel)

Menggunakan struct Menggunakan class

#include <iostream> #include <iostream>


#include <cmath> #include <cmath>

long kuadrat(int a){ class titik{


return a*a; public:
} void input() {
std::cout << "masukkan x : ";
float jarak(int x1, int y1, int x2, int y2) { std::cin >> x;

return sqrt (kuadrat(x2-x1) + kuadrat(y2- std::cout << "masukkan y : ";


y1));
std::cin >> y;
}
}
struct titik{

Bab 2 Kelas (class) halaman 22


int x = 0; long kuadrat(int a){
int y = 0; return a*a;
}; }

int main() { float jarak(titik B) {


titik A, B; return sqrt (kuadrat(x-B.x) + kuadrat(y-
B.y));

}
std::cin >> B.x >> B.y;
std::cout << "Hello World!\n";
titik () {//constructor class titik
std::cout << "Jarak titik = " <<
jarak(A.x,A.y,B.x,B.y); x = 0;
} y = 0;
}

private:
int x;
int y;
};

int main() {

titik A, B;

B.input();
std::cout << "Hello World!\n";
std::cout << "Jarak titik = " <<
A.jarak(B);
}

Bab 2 Kelas (class) halaman 23


Perhatikan perubahan dari struct menjadi class. Progam menggunakan struct (di
sebelah kiri) dan progam menggunakan class (di sebelah kanan). Pada dasar nya struct
semua anggota nya bersifat public

Kelas adalah salah satu abstraksi (pemodelan) data atau disebut juga
abstract data type. Konstruksi kelas adalah sebagai berikut :
class nama-kelas {
// bagian
public public :
// bagian private
private :
// bagian protected
protected :
};

Biasanya, data termasuk pada bagian private (information hiding), sedangkan


method (fungsi) berada pada bagian public. Pada bagian public inilah setiap objek
dari kelas tersebut dapat saling berkomunikasi lewat message passing (pertukaran
pesan). Method biasanya merupakan fungsi yang memanipulasi data dari kelas yang
bersangkutan.

B. Kelas Currency
Untuk mempelajari kelas, kita gunakan kelas currency untuk contoh. Objek
dari setiap kelas currency ini akan mempunyai method sebagai berikut:
a. memberikan nilai ke objek

b. menentukan komponen (tanda, banyaknya dollar, maupun banyaknya sen)

c. menambah dua objek bertipe currency


d. menaikkan nilai

e. menampilkan output tipe currency

Bab 2 Kelas (class) halaman 24


Di bawah ini diberikan konstruksi dari kelas tipe currency.
Program 2.1. Kelas Currency
1. #include <iostream.h>
2. #include <stdlib.h>
3. #include "bool.h"
4. enum sign {plus, minus};
5. class Currency {
6. public:
7. Currency(sign s = plus, unsigned long d = 0, unsigned int c = 0);
8. ~Currency() {}
9. bool Set(sign s, unsigned long d, unsigned int c);
10. bool Set(float a);
11. sign Sign() const {return sgn;}
12. unsigned long Dollars() const {return dollars;}
13. unsigned int Cents() const {return cents;}
14. Currency Add(const Currency& x) const;
15. Currency& Increment(const Currency& x);
16. void Output() const;
17. private:
18. sign sgn;
19. unsigned long dollars;
20. unsigned int cents;
21. };

Kelas Currency mempunyai 3 data member, yaitu sgn yang mempunyai


kemungkinan nilai plus atau minus, dollars untuk menyimpan nilai utuh dari
pecahan dollar dan cents untuk menyimpan nilai pecahan. Misalnya $1.25 akan
disimpan sebagai dollars = 1, dan cents = 25, sedangkan sgn bernilai plus.

Method Set digunakan untuk mengubah data member. Terdapat dua method
Set, yang pertama mempunyai 3 parameter yang langsung menspesifikasi setiap data
member. Sementara yang kedua bertipe float yang nantinya harus dipecah menjadi 3
bagian seperti halnya 3 data member, yaitu tanda, bagian dollar dan bagian sen

Bab 2 Kelas (class) halaman 25


Preprocessor (1), (2), dan diakhiri #endif digunakan untuk menjamin bahwa
kelas Currency hanya akan dikompilasi sekali. Isi dari bool.h adalah sebagai berikut
:

Program 2.2. Definisi boolean (bool.h)


1. #ifndef bool_
2. #define bool_
3.
4. typedef int bool;
5. const bool false = 0;
6. const bool true = 1;
7.
8. #endif

Tipe bool mempunyai dua alternatif harga yaitu false dan true. False untuk
menggantikan nilai 0, sedangkan true untuk menggantikan nilai 1.

Program 2.3. Konstruktor kelas Currency.


1. Currency::Currency(sign s, unsigned long d, unsigned int c)
2. {
3. if (c > 99)
4. {
5. cerr << "Cents should be < 100" << endl;
6. exit(1);}
7. sgn = s; dollars = d; cents = c;
8. }

Konstruktor Currency langsung dispesifikasi membentuk objek Currency


yang terdiri dari tanda, bagian dollar dan bagian sen. Khusus bagian sen, oleh
karena 1 dollar sama dengan 100 sen maka harga c tidak boleh melebihi 99 (3),
yang apabila dilanggar akan memberikan sinyal error (5) dan keluar dari program
(6). Pembentukan objek dilakukan dengan meng-assign pada setiap data member
(7), berturut-turut s meng-assign sgn, d meng-assign dollars, dan c meng-assign
cents.

Bab 2 Kelas (class) halaman 26


Program 2.4. Memberikan harga pada objek dengan 3 komponen.
1. bool Currency::Set(sign s, unsigned long d, unsigned int c)
2. {
3. if (c > 99) return false;
4. sgn = s; dollars = d; cents = c;
5. return true;
6. }

Untuk mengubah data member, selain pada saat dibuat objeknya, kita dapat
mengubahnya dengan method Set yang perilakunya mirip dengan konstruktor
Currency. Hanya saja method Set ini akan mengembalikan nilai true jika berhasil
melakukan perubahan, false jika terjadi kesalahan, artinya data member tidak
diubah nilainya.
Program 2.5. Memberikan harga pada objek dengan tipe float dan
kemudian mengkonversinya ke bentuk komponen demi komponen.
1. bool Currency::Set(float a)
2. {
3. if (a < 0) {sgn = minus; a = -a;}
4. else sgn = plus;
5. dollars = a;
6. cents = (a + 0.001 - dollars) * 100;
7. return true;
8. }

Method Set dengan parameter bertipe float digunakan untuk mengubah data
member dengan memecah a menjadi unsur-unsur ketiga data member Currency.
Yang pertama, apakah a bernilai negatif atau positif. Jika negatif maka tanda sgn
akan diberi nilai minus (3), dan nilai a harus selalu berharga positif (a = -a). Jika
positif nilai sgn diberi nilai plus (4). Oleh karena dollars bertipe long (int) maka (5)
akan mengambil nilai integernya saja (menggunakan konversi nilai). Sementara (6)
mengambil nilai sen dengan cara nilai float a dikurangi dengan bagian integernya,
dan supaya bernilai bulat maka dikalikan dengan 100. Method ini selalu
mengembalikan nilai true (7).

Bab 2 Kelas (class) halaman 27


Program 2.6. Method untuk menjumlahkan dua
objek bertipe currency
1. Currency Currency::Add(const Currency& x) const
2. {
3. long a1, a2, a3;
4. Currency ans;
5. a1 = dollars * 100 + cents;
6. if (sgn == minus) a1 = -a1;
7. a2 = x.dollars * 100 + x.cents;
8. if (x.sgn == minus) a2 = -a2;
9. a3 = a1 + a2;
10. if (a3 < 0) {ans.sgn = minus; a3 = -a3;}
11. else ans.sgn = plus;
12. ans.dollars = a3 / 100;
13. ans.cents = a3 - ans.dollars * 100;
14. return ans;
15. }

Method Add digunakan untuk menambahkan sebesar x pada suatu objek


Currency. Pertama, nilai objek dikonversikan menjadi sen dan disimpan pada a1 (5).
Kita hanya akan memperlakukan setiap nilai dengan harga aslinya (6). Kedua, x
juga dikonversi menjadi sen dan disimpan pada a2 (7). Harga a2 juga diambil harga
aslinya (8). Ketiga, kedua nilai tadi kemudian dijumlahkan (9) disimpan pada a3.
Yang perlu diingat adalah bahwa baik dollars maupun cents selalu berharga positif.
Untuk itu operasi penambahan maupun pengurangan sebenarnya menggunakan
operasi aritmetika biasa, sehingga kita perlu mengkonversi setiap objek dengan
harga aslinya. Misalnya sgn = minus, dollars = 3, dan cents = 25 berarti harga
aslinya adalah -3.25.
Langkah terakhir, nilai a3 dikembalikan menjadi bentuk objek, sgn diberi
nilai dan a3 menjadi harga mutlak (10). Nilai dollars diambil nilai integernya saja
(12), kemudian nilai cents diambil dengan cara nilai a3 dikurangi nilai integernya
(13). Harga ans dikembalikan sebagai hasil penambahan (14).
Method Add dapat dipandang sebagai operator + dalam halaman ini.

Bab 2 Kelas (class) halaman 28


Program 2.7. Method untuk menaikkan nilai objek sebanyak x.
1. Currency& Currency::Increment(const Currency& x)
2. {
3. *this = Add(x);
4. return *this;
5. }

Method Increment menggunakan method Add untuk memanipulasi data


member (3). Hanya saja, nilai objek "ini" (dan bukan objek lain) yang bertambah
nilainya dengan x (4). Method Increment dapat dipandang sebagai operator +=.
Program 2.8. Method untuk mencetak objek bertipe
currency
1. void Currency::Output() const
2. {
3. if (sgn == minus) cout << '-';
4. cout << '$' << dollars << '.';
5. if (cents < 10) cout << "0";
6. cout << cents;
7. }

Method Output digunakan untuk mencetak objek Currency. Kitapun juga bisa
mengubahnya untuk mata uang yang lain.
Program 2.9. Main fungsi untuk menguji-coba kelas currency
1. #include <iostream.h>
2. #include "curr1.h"
3. void main(void)
4. { Currency g, h(plus, 3, 50), i, j;
5. g.Set(minus, 2, 25);
6. i.Set(-6.45);
7. j = h.Add(g);
8. j.Output(); cout << endl;
9. i.Increment(h);
10. i.Output(); cout << endl;
11. j = i.Add(g).Add(h);
12. j.Output(); cout << endl;
13. j = i.Increment(g).Add(h);
14. j.Output(); cout << endl;
15. i.Output(); cout << endl;
16. }

Bab 2 Kelas (class) halaman 29


Pada fungsi main dideklarasikan 4 objek Currency yaitu g, h, i, dan j (5).
Khusus objek h langsung diberi nilai awal $3.50. Objek g di-set bernilai -$2.25 (6).
Objek i di-set bernilai -$6.45 (7).
Objek j merupakan hasil penjumlahan dari h dan g, sehingga j bernilai $1.25
(8). Objek i ditambahkan nilainya dengan h menjadi -$2.95 (10). Kemudian objek j
merupakan hasil penjumlahan dari objek i, g dan h (12) menjadi bernilai -$1.70.
Cara lain operasi ini dengan menggunakan (14). Namun perbedaannya adalah nilai i
bertambah dengan g, sedangkan pada (12) nilai i tidak bertambah nilainya. Output
selengkapnya dari fungsi main di atas adalah sebagai berikut :
$1.25
-$2.95
-$1.70
-$1.70
-$5.20

Di bawah ini diberikan tipe data abstrak yang berbeda untuk kelas currency.
Program 2.10. Versi 2 : Kelas Currency dengan menggunakan
representasi yang berbeda
1. enum sign {plus, minus};
2. class Currency {
3. public:
4. Currency(sign s = plus, unsigned long d = 0, unsigned int c = 0);
5. ~Currency() {}
6. bool Set(sign s, unsigned long d, unsigned int c);
7. bool Set(float a);
8. sign Sign() const {if (amount < 0) return minus; else return plus;}
9. unsigned long Dollars() const
10. {if (amount < 0) return (-amount) / 100;
11. else return amount / 100;}
12. unsigned int Cents() const
13. {if (amount < 0) return -amount - Dollars() * 100;
14. else return amount - Dollars() * 100;}
15. Currency Add(const Currency& x) const;
16. Currency& Increment(const Currency& x)
17. {amount += x.amount; return *this;}
18. void Output() const;
19. private:

Bab 2 Kelas (class) halaman 30


20. long amount;
21. };
Implementasi method dari kelas Currency di atas selengkapnya diberikan berikut
ini:

Program 2.11. Implementasi method kelas Currency versi 2


1. Currency::Currency(sign s, unsigned long d, unsigned int c)
2. {
3. if (c > 99)
4. {// too many cents
5. cerr << "Cents should be < 100" << endl;
6. exit(1);}
7. amount = d * 100 + c;
8. if (s == minus) amount = -amount;
9. }

10. bool Currency::Set(sign s, unsigned long d, unsigned int c)


11. {// Reset value.
12. if (c > 99) return false;
13. amount = d * 100 + c;
14. if (s == minus) amount = -amount;
15. return true;
16. }

17. bool Currency::Set(float a)


18. {
19. sign sgn;
20. if (a < 0) {sgn = minus; a = -a;}
21. else sgn = plus;
22. amount = (a + 0.001) * 100;
23. if (sgn == minus) amount = -amount;
24. return true;
25. }

26. Currency Currency::Add(const Currency& x) const


27. {
28. Currency y;
29. y.amount = amount + x.amount;
30. return y;

Bab 2 Kelas (class) halaman 31


31. }

32. void Currency::Output() const


33. {
34. long a = amount;
35. if (a < 0) {
36. cout << '-';
37. a = -a;}
38. long d = a / 100;
39. cout << '$' << d << '.';
40. int c = a - d * 100;
41. if (c < 10) cout << "0";
42. cout << c;
43. }

A. Operator Overloading
Pada kelas Currency di atas, method Add dapat dipandang sebagai operator
+, sedangkan method Increment dapat dipandang sebagai operator +=. Namun kita
dapat menggunakan baik operator + maupun += dengan cara meng-overload-nya.
Operator yang demikian dinamakan operator overloading (operator berbeban lebih).
Untuk itu kelas Currency di atas kita ubah menjadi versi ketiga berikut ini.

Program 2.12. Versi 3 : Kelas Currency dengan menggunakan


Operator overloading
1. enum sign {plus, minus};
2. class Currency {
3. public:
4. Currency(sign s = plus, unsigned long d = 0, unsigned int c = 0);
5. ~Currency() {}
6. bool Set(sign s, unsigned long d, unsigned int c);
7. bool Set(float a);
8. sign Sign() const
9. {if (amount < 0) return minus; else return plus;}
10. unsigned long Dollars() const
11. {if (amount < 0) return (-amount) / 100; else return amount / 100;}
12. unsigned int Cents() const
13. {if (amount < 0) return -amount - Dollars() * 100;
14. else return amount - Dollars() * 100;}

Bab 2 Kelas (class) halaman 32


15. Currency operator+(const Currency& x) const;

16. Currency& operator+=(const Currency& x)


17.
{amount += x.amount; return *this;}
18. void Output(ostream& out) const;
19.
private:
20.
long amount;
21. };

Operator overloading dari + terlihat pada (15), sedangkan += terlihat pada

(16).

Program 2.13. Implementasi method kelas Currency versi 3


menggunakan operator overloading
1. Currency::Currency(sign s, unsigned long d, unsigned int c)
2. {
3. if (c > 99)
4. {
5. cerr << "Cents should be < 100" << endl;
6. exit(1);}
7. amount = d * 100 + c;
8. if (s == minus) amount = -amount;
9. }

10. bool Currency::Set(sign s, unsigned long d, unsigned int c)


11. {
12. if (c > 99) return false;
13. amount = d * 100 + c;
14. if (s == minus) amount = -amount;
15. return true;
16. }

17. bool Currency::Set(float a)


18. {
19. sign sgn;
20. if (a < 0) {sgn = minus; a = -a;}
21. else sgn = plus;
22. amount = (a + 0.001) * 100;
23. if (sgn == minus) amount = -amount;
24. return true;
25. }

Bab 2 Kelas (class) halaman 33


26. Currency Currency::operator+(const Currency& x) const
27. {
28. Currency y;
29. y.amount = amount + x.amount;
30. return y;
31. }

32. void Currency::Output(ostream& out) const


33. {
34. long a = amount;
35. if (a < 0) {
36. out << '-';
37. a = -a;}
38. long d = a / 100; // dollars
39. out << '$' << d << '.';
40. int c = a - d * 100; // cents
41. if (c < 10) out << "0";
42. out << c;
43. }

44. // overload operator <<


45. ostream& operator<<(ostream& out, const Currency& x)
46. {x.Output(out); return out;}

47. // main function untuk kelas Currency versi 3


48. #include <iostream.h>
49. #include "curr3.h"

50. void main(void)


51. {
52. Currency g, h(plus, 3, 50), i, j;
53. g.Set(minus, 2, 25);
54. i.Set(-6.45);
55. j = h + g;
56. cout << j << endl;
57. i += h;
58. cout << i << endl;
59. j = i + g + h;
60. cout << j << endl;
61. j = (i+=g) + h;
62. cout << j << endl;
63. cout << i << endl;
64. }

Bab 2 Kelas (class) halaman 34


A. Penanganan Perkecualian
Kelas Currency di bawah ini telah dilengkapi dengan fasilitas penanganan
perkecualian.
Program 2.14. Kelas Currency dengan penanganan kesalahan
1. #include <iostream.h>
2. #include <stdlib.h>
3. #include "xcept.h"
4. #include "bool.h"

5. enum sign {plus, minus};


6. class Currency {
7. public:
8. Currency(sign s = plus, unsigned long d = 0, unsigned int c = 0);
9. ~Currency() {}
10. void Set(sign s, unsigned long d, unsigned int c);
11. void Set(float a);
12. sign Sign() const
13. {if (amount < 0) return minus;
14. else return plus;}
15. unsigned long Dollars() const
16. {if (amount < 0) return (-amount) / 100;
17. else return amount / 100;}
18. unsigned int Cents() const
19. {if (amount < 0) return -amount - Dollars() * 100;
20. else return amount - Dollars() * 100;}
21. Currency operator+(const Currency& x) const;
22. Currency& operator+=(const Currency& x)
23. {amount += x.amount; return *this;}
24. void Output(ostream& out) const;
25. private:
26. long amount;
27. };

Program 2.15. Implementasi Kelas Currency dengan


penanganan kesalahan
1. Currency::Currency(sign s, unsigned long d, unsigned int c)
2. {

Bab 2 Kelas (class) halaman 35


3. if (c > 99) throw BadInitializers();
4. amount = d * 100 + c;
5. if (s == minus) amount = -amount;
6. }
7.
8. void Currency::Set(sign s, unsigned long d, unsigned int c)
9. {
10. if (c > 99) throw BadInitializers();
11. amount = d * 100 + c;
12. if (s == minus) amount = -amount;
13. }
14.
15. void Currency::Set(float a)
16. { sign sgn;
17. if (a < 0) {sgn = minus; a = -a;}
18. else sgn = plus;
19. amount = (a + 0.001) * 100;
20. if (sgn == minus) amount = -amount;
21. }

22. Currency Currency::operator+(const Currency& x) const


23. {
24. Currency y;
25. y.amount = amount + x.amount;
26. return y;
27. }

28. void Currency::Output(ostream& out) const


29. {
30. long a = amount;
31. if (a < 0) {out << '-';
32. a = -a;}
33. long d = a / 100;
34. out << '$' << d << '.';
35. int c = a - d * 100;
36. if (c < 10) out << "0";
37. out << c;
38. }
39. // overload <<
40. ostream& operator<<(ostream& out, const Currency& x)
41. {x.Output(out); return out;}

42. #include <iostream.h>

Bab 2 Kelas (class) halaman 36


43. #include "curr4.h"

44. void main(void)


45. {
46. Currency g, h(plus, 3, 50), i, j;
47. g.Set(minus, 2, 25);
48. i.Set(-6.45);
49. j = h + g;
50. cout << j << endl;
51. i += h;
52. cout << i << endl;
53. j = i + g + h;
54. cout << j << endl;
55. j = (i+=g) + h;
56. cout << j << endl;
57. cout << i << endl;
58. }

A. Anggota kelas friend dan protected


Pada program 2.14. untuk meng-overload operator <<, kita masih
menggunakan method Output (27). Kita dapat menggunakan friend agar langsung
bisa menggunakan bagian private dari kelas Currency. Kelas yang demikian
diberikan di bawah ini :
Program 2.15. Kelas Currency menggunakan friend untuk meng-
overload operator <<
1. #include <iostream.h>
2. #include <stdlib.h>
3. #include "bool.h"

4. enum sign {plus, minus};


5. class Currency {
6. friend ostream& operator<<(ostream&, const Currency&);
7. public:
8. Currency(sign s = plus, unsigned long d = 0, unsigned int c = 0);
9. ~Currency() {}
10. bool Set(sign s, unsigned long d, unsigned int c);
11. bool Set(float a);
12. sign Sign() const
13. {if (amount < 0) return minus;

Bab 2 Kelas (class) halaman 37


14. else return plus;}
15. unsigned long Dollars() const
16. {if (amount < 0) return (-amount) / 100;
17. else return amount / 100;}
18. unsigned int Cents() const
19. {if (amount < 0) return -amount - Dollars() * 100;
20. else return amount - Dollars() * 100;}
21. Currency operator+(const Currency& x) const;
22. Currency& operator+=(const Currency& x)
23. {amount += x.amount; return *this;}
24. private:
25. long amount;
26. };

Di bawah ini diberikan implementasi dari operator overloading


<< menggunakan friend. Objek Currency x dikirim untuk dicetak bagian
private-nya.
Program 2.16. Implementasi overloading operator <<
dengan friend
1. // overload <<
2. ostream& operator<<(ostream& out, const Currency& x)
3. {
4. long a = x.amount;
5. if (a < 0) {out << '-';
6. a = -a;}
7. long d = a / 100;
8. out << '$' << d << '.';
9. int c = a - d * 100;
10. if (c < 10) out << "0";
11. out << c;
12. return out;
13. }

14. // main fungsi untuk kelas Currnecy versi 5


15. #include <iostream.h>
16. #include "curr5.h"

17. void main(void)


18. {
19. Currency g, h(plus, 3, 50), i, j;
20. g.Set(minus, 2, 25);
21. i.Set(-6.45);

Bab 2 Kelas (class) halaman 38


22. j = h + g;
23. cout << j << endl;
24. i += h;
25. cout << i << endl;
26. j = i + g + h;
27. cout << j << endl;
28. j = (i+=g) + h;
29. cout << j << endl;
30. cout << i << endl;
31. }

Latihan
Diberikan kelas Himpunan sebagai berikut :

class Himpunan {
friend ostream& operator<<(ostream&, const Himpunan&);
public :
Himpunan();
Himpunan(int);
Himpunan(char
*);
int member(const Himpunan&, char);
Himpunan operator+(const
Himpunan&); Himpunan operator-(const
Himpunan&); Himpunan
operator*(const Himpunan&);
Himpunan& sisip_elemen(char);
Himpunan& hapus_elemen(char);
int cari(char);
Himpunan selisih_simetrik(Himpunan&,
Himpunan&); char operator[](int) const;
int
ukurannya();
private :
int
ukuran;
char *A;
};

Fungsi main untuk implementasi kelas Himpunan adalah sebagai berikut :

1. void main() {
2. char *s1 = "aabcadeak";
3. char *s2 = "abfg";
4. char *s3;
5. Himpunan A(s1), B(s2), C(5), D;

Bab 2 Kelas (class) halaman 39


6. cout << "A : " << A << endl;
7. cout << "B : " << B << endl;
8. cout << "Ukuran dari himpunan : " << B.ukurannya() <<
endl; 9. cout << "B(2) : " << B[2] << endl;
10. cout << "D : " << D << endl;
11. D = B;
12. cout << "D(now) : " << D << endl;
13. cout << "Ukuran dari himpunan : " << D.ukurannya() << endl;
14. if (A.member(A,'c')) cout << 'c' << " anggota A" << endl;
15. else cout << 'c' << " bukan anggota A" << endl;
16. cout << B << endl;
17. cout << "C : " << C << endl;
18. cout << "Himpunan : " << A << " union " << B << " : " << A+B << endl;
19. cout << "Himpunan : " << A << " minus " << B << " : " << A-B << endl;
20. cout << "Himpunan : " << B << " minus " << A << " : " << B-A << endl;
21. cout << "Himpunan : " << A << " irisan " << B << " : " << A*B << endl;
22. char c;
23. cout << "Masukkan elemen yang akan disisipkan : "; cin >> c;
24. B.sisip_elemen(c);
25. cout << B;
26. cout << "\nCari elemen ? "; cin >> c;
27. if (A.cari(c))
28. cout << "Elemen : " << c << " terletak pada posisi : " << A.cari(c) << endl;
29. else cout << c << " tidak ada pada " << A << endl;
30. cout << "A : " << A << "\nHapus elemen ? "; cin >> c;
31. A.hapus_elemen(c);
32. cout << A;
33. cout << "\nSelisih simetrik " << A << " dan " << B
34. << " : " << B.selisih_simetrik(A,B);
35. }

Buatlah :
1. konstruktor untuk kelas Himpunan dengan deklarasi baris 5.

2. operator overloading -, +, *, dan [ ].

Bab 2 Kelas (class) halaman 40


SKENARIO PEMBELAJARAN MINGGU 3

Persiapan [50 menit]

01. Mahasiswa mengerjakan Pretest Praktikum


02. Mahasiswa mempelajari kaedah perulangan secara interatif dan rekursif
03. Mahasiswa membuat contoh menggunakan 3 jenis perulangan interatif
04. Mahasiswa mengkonversi perulangan interatif menjadi rekursif
05. Catatan :
a. Boleh belajar bersama kelompok masing-masing

b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]

00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing

01. Dosen membuka perkuliahan


02. Dosen memberikan contoh perulangan secara interatif dan rekursif
03. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
04. Dosen menjelaskan pembuatan Class dari Struct
05. Mahasiswa mengikuti dengan compilernya masing-masing
06. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]

01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya masing-


masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]

01. Dosen memberikan rangkuman materi kuliah minggu ini


02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 3 Rekursi halaman 41


Bab III

Rekursi

Tujuan Pembelajaran:

1. Mahasiswa mampu mengkonstruksikan perulangan iteratif

2. Mahasiswa mampu memahami karakteristik fungsi iteratif dan rekursif

3. Mahasiswa mampu mengkonversi fungsi iteratif ke rekursif dan sebaliknya

A. Pendahuluan

Prinsip dasar rekursi mengikuti definisi rekursi (relasi rekurensi), lihat materi matematika
diskrip sebagai contoh kasus menghitung n! secara definisi rumus faktorial adalah n! = n.(n-
1)! Dengan ketentuan 0!=1 atau 1!=1

Cara membaca dari relasi rekuensi n! adalah hasil yang di peroleh dari perkalian di bawah ini

Yaitu sebanyak n suku. Contoh di atas bila n nya sama dengan 5 berarti hasil akhirnya sama
dengan 120

Dalam istilah rekursi harus memenuhi dua ketentuan berikut. Langkah rekursi :

Untuk menghitung n!, ambil satu suku yaitu n lalu lakukan operasi yaitu kali kemudian
menggunakan operasi yang sama untuk sisa suku yang belum di hitung yaitu n-1 dengan
operasi yang sama (n-1)!

Langkah basis :

Langkah di mana proses rekursi berhenti. Dalam hal ini bila n=0 atau n=1 nilai rekusi nya
adalah 1

Bab 3 Rekursi halaman 42


Dalam pemrogaman, dengan operasi yang sama di artikan sebagai memanggil diri nya sendiri
fungsi yang memanggil nama fungsi itu sendiri .

Perhatikan kode di bawah ini :

Dalam pernyataan kondisional if, n<=1 telah mengakomodasi ketentuan faktorial untuk n=1
dan n=0. Hasil faktorial nya adalah 1 dengan pernyataan return 1. Untuk kasus pemanggilan
rekursi (rekursif call) mengakomodasi pemanggilan rekursi n.(n-1)! Menggunakan
pernyataan return n*factorial (n-1)

Disinilah fungsi faktorial di panggil dirinya sendiri. Untuk menelusuri proses rekursi lihat
dalam gambar berikut:

Selama pemanggilan rekursi akan berlaku proses ekspansi (expansion) sesuai rumus faktorial

Sebagai contoh factorial (5) ambil suku terbesar yaitu 5 di kalikan factorial 5-1 yaitu factorial
4

Bab 3 Rekursi halaman 43


Faktor ekspansi dilakukan terus menerus sampai tercapai langkah basis (base step) yaitu saat
n mencapai 1 yaitu factorial (1) yang bernilai 1. Setelah nilai basis tercapai berlaku proses
kontraksi sehingga di peroleh nilai akhir 5!=120

B. Kasus diskusi

Lakukan dengan cara yang sama untuk menghitung deret fibonacci

C. Kasus 3 diskusi

Hitunglah greatest common divisor

D. Latihan

1. Kasus menghitung n faktorial pada dasarnya menjadi ide untuk di terapkan pada
array. Angka dalam kasus faktorial di anggap menjadi indeks di dalam array. Buatlah:

a. Prosedur untuk mencetak elemen array secara iteratif

b. Prosedur untuk mencetak elemen array secara rekursif

Bab 3 Rekursi halaman 44


c. Dari poin a dan b lakukan dari indeks 0 sampai n-1 dan sebaliknya

2. Kembali ke kasus perhitungan n faktorial. Bisa di kembangkan untuk fokus pada


bilangan ganjil atau bilangan genap. Buatlah:

a. Fungsi yang menghitung isi array indeks ganjil

b. Fungsi yang menghitung isi array indeks genap

c. Poin a dan b lakukan secara iteratif dalam satu prosedur dengan dua output yaitu
jumlah ganjil dan jumlah genap

d. Lakukan poin c dengan cara rekursif

Bab 3 Rekursi halaman 45


SKENARIO PERKULIAHAN MINGGU 4

Persiapan [50 menit]


01. Mahasiswa mengerjakan Pretest Praktikum
02. Mahasiswa mempelajari Array Statis dan Array Dinamis
03. Mahasiswa mencari perbedaan Array Statis dan Array Dinamis
04. Mahasiswa membuat contoh Array Statis dan Array Dinamis
05. Catatan :
a. Boleh belajar bersama kelompok masing-masing
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Uji Kompetensi [20 menit]


01. Dosen memberikan soal dengan materi Array Statis dan Array Dinamis
02. Mahasiswa mengerjakan uji kompetensi tahap 1
03. Mahasiswa mengumpulkan lembar jawaban uji kompetensi

Kegiatan Kuliah [40 menit]


00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-
masing
01. Dosen membuka perkuliahan
02. Dosen memberikan contoh Array Statis dan Array Dinamis
03. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
04. Dosen menjelaskan pembuatan Array Statis dan Array Dinamis
05. Mahasiswa mengikuti dengan compilernya masing-masing
06. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]


01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya
masing-masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]


01. Dosen memberikan rangkuman materi kuliah minggu ini
02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 4 Array halaman 46


Bab IV

Array
Tujuan Pembelajaran
1. mahasiswa memahami array statis dan array dinamis menggunakan C++

2. mahasiswa dapat menerapkan konsep array dalam kasus yang berkaitan


dengan array dalam bahasa pemrograman C++

A. Pendahuluan

Array adalah struktur data yang mengandung type data yang mempunyai type
sama. Suatu array adalah sekelompok memori yang berhubungan. Array mempunyai
nama dan type yang sama. Untuk merujuk lokasi tertentu atau elemen dalam array;
nama array dan angka posisi (disebut subscript atau indeks) dari elemen tersebut
dalam array.

B. Tipe Data Abstrak Array Satu Dimensi Statis

Deklarasi array ditentukan dengan tipe dari setiap elemen dan banyaknya
elemen yang diperlukan oleh setiap array sehingga komputer mempersiapkan
sejumlah memori. Tipe data abstrak dari array 1 dimensi statis dapat dibuat
sebagaimana berikut ini.
Program 3.1. Kelas Array1D, ADT untuk array statis satu dimensi
1. #include <iostream.h>
2. #define maks 5
3. class Array1D {
4. friend ostream& operator<<(ostream&, const Array1D&);
5. friend istream& operator>>(istream&, Array1D&);
6. public :
7. Array1D();
8. void cetak();
9. void geser_kiri();
10. void geser_kanan();
11. private :
12. char A[maks];
13. };

Bab 4 Array halaman 47


Data member satu-satunya adalah A yaitu array (statis) dengan ukuran tertentu
maks, yang didefinisikan sebanyak 5 elemen (12). Di bagian public ada 1
konstruktor dan 3 method, yaitu cetak yang digunakan untuk mencetak array A,
geser_kiri untuk menggeser elemen ke kiri sebanyak satu elemen secara melingkar,
dan geser_kanan untuk menggeser elemen ke kanan sebanyak satu elemen secara
melingkar. Ada dua friend yang meng-overload operator input >> dan operator
output <<.

Program 3.2. Konstruktor kelas Array1D


1. Array1D::Array1D()
2. {
3. for (int i=0; i<maks; i++)
4. A[i] = '0';
5. }

Konstruktor kelas Array1D digunakan untuk menginisialisasi kelas Array1D


mengisinya dengan karakter ‘0’‛ sebagai tanda isi array masih kosong. Ingat bahwa
array dalam C++ indeksnya dimulai dari 0 sampai dengan maks-1.

Program 3.3. Mencetak setiap elemen array


1. void Array1D::cetak()
2. {
3. for (int i=0; i<maks; i++)
4. cout << A[i] << " ";
5. }

Coba bandingkan program 3.3. dan program 3.4 di bawah ini. Kedua method
tersebut mempunyai fungsi yang sama yaitu mencetak bagian private kelas Array1D
namun dengan cara yang berbeda. Satu sebagai function yang dapat mengakses array
A dan merupakan anggota kelas, sedangkan yang lain bukan anggota kelas namun
sebagai friend. Keduanya dapat memanipulasi bagian private array A.

Program 3.4. Overloading operator output << untuk kelas Array1D


1. ostream& operator<<(ostream& out, const Array1D& x)

Bab 4 Array halaman 48


2. {
3. for (int i=0; i<maks; i++)
4. cout << x.A[i] << " ";
5. cout << endl;
6. return out;
7. }

Overloading operator input >> akan memberikan keleluasaan kita untuk


memasukkan data sesuai dengan kelas yang kita ciptakan. Seperti halnya operator
output <<, kita juga mengoverload operator >> sebagai friend dari kelas Array1D.
Ciri khasnya terlihat pada tipe data yang dikirim pada parameter formalnya, yaitu
bertipe Array1D.
Program 3.5. Overloading operator input >> untuk kelas Array1D
1. istream& operator>>(istream& in, Array1D& x)
2. { int posisi;
3. cout << "Mengisi array pada posisi ke : ";
4. in >> posisi;
5. if (posisi > 0 && posisi <= maks) {
6. cout << "Masukkan elemen array-nya : ";
7. in >> x.A[posisi-1];
8. }
9. else
10. cout << "Anda memasukkan posisi di luar range ... ";
11. return in;
12. }

Method geser_kanan di bawah dapat dijelaskan sebagai berikut. Perhatikan


gambar logik dari array berikut :
Nilai tersimpan -2 4 -1 5 3
Indeks 0 1 2 3 4

Misalkan kita putar ke kanan, maka indeks terakhir yaitu keempat perlu disimpan
dulu ke temp (4). Kemudian elemen ke-3 akan menempati posisi ke-4, sampai
dengan elemen ke-0 menempati posisi ke-1 (5 dan 6). Elemen ke-0 dapat “dianggap”
kosong, kemudian ditempati oleh elemen ke-4 yang tersimpan pada temp (7). Method
geser_kanan diberikan di bawah ini.

Bab 4 Array halaman 49


Program 3.6. Method untuk menggeser elemen ke kanan
1. void Array1D::geser_kanan()
2. {
3. int n = maks;
4. int temp = A[n-1];
5. for (int i=n-1; i >= 0; i--)
6. A[i+1] = A[i];
7. A[0] = temp;
8. }

Algoritma menggeser elemen ke kiri mempunyai cara yang serupa. Hanya


saja, elemen yang “diselamatkan” adalah elemen ke-0, kemudian elemen ke-0 dari
elemen ke-1 sampai dengan elemen ke-3 dari elemen ke-4. Yang perlu diperhatikan
adalah perulangan for. Pada method geser_kanan, perulangannya menurun,
sedangkan pada method geser_kiri, perulangannya menaik.

Program 3.7. Method untuk menggeser elemen ke kiri


1. void Array1D::geser_kiri()
2. {
3. int n = maks;
4. int temp = A[0];
5. for (int i=0; i < n; i++)
6. A[i] = A[i+1];
7. A[n-1] = temp;
8. }

Fungsi main yang digunakan untuk menguji-coba array statis kelas Array1D
disajikan berikut ini.

Program 3.8. Fungsi main yang digunakan untuk


menguji-coba kelas Array1D
1. main() {
2. Array1D x;
3. cout << "Array masih kosong : " << x;
4. cin >> x;
5. cout << "Isi Array saat ini : " << x;
6. x.geser_kiri();
7. cout << "Isi Array setelah digeser ke kiri : " << x;

Bab 4 Array halaman 50


8. x.geser_kanan();
9. cout << "Isi Array setelah digeser ke kanan : " << x;
10. return 0;
11. }

C. Tipe Data Abstrak Array Satu Dimensi Dinamis


Adakalanya kita menginginkan pengelolaan array yang banyaknya elemen
akan bervariasi sesuai dengan yang dibutuhkan pada saat program dijalankan. Oleh
karena array pada dasarnya adalah pointer (ingat bahwa nama array adalah alamat
pertama dari array), kita dapat memanfaatkannya untuk membuat tipe data abstrak
array dinamis. Tipe data abstrak dari array 1 dimensi dinamis dapat dibuat
sebagaimana berikut ini.

Program 3.9. Kelas array satu dimensi dinamis


1. template<class T>
2. class Array1D {
3. friend ostream& operator<< (ostream&, const Array1D<T>&);
4. public:
5. Array1D(int size = 0);
6. Array1D(const Array1D<T>& v);
7. ~Array1D() {delete [] element;}
8. T& operator[](int i) const;
9. int Size() {return size;}
10. Array1D<T>& operator=(const Array1D<T>& v);
11. Array1D<T> operator+() const;
12. Array1D<T> operator+(const Array1D<T>& v) const;
13. Array1D<T> operator-() const;
14. Array1D<T> operator-(const Array1D<T>& v) const;
15. Array1D<T> operator*(const Array1D<T>& v) const;
16. Array1D<T>& operator+=(const T& x);
17. Array1D<T>& ReSize(int sz);
18. private:
19. int size;
20. T *element;
21. };

Bab 4 Array halaman 51


Kelas Array1D mempunyai private data member 2 buah yaitu size bertipe int
(19), yang menyatakan banyak elemen dari array, dan pointer element yang
menyatakan array itu sendiri (20). Banyaknya elemen array element ditentukan
berdasarkan size.

Program 3.10. Konstruktor array satu dimensi


1. template<class T>
2. Array1D<T>::Array1D(int sz)
3. {
4. size = sz;
5. element = new T[sz];
6. }

Konstruktor kelas Array1D ukurannya ditentukan dari luar kelas sebesar sz

(2) yang di-assign ke data member size (4), kemudian dipesan memori sebanyak sz

untuk array element (5).

Kita dapat menyalin dengan cara meng-assign setiap elemen array ke variabel
array yang lain dengan menggunakan konstruktor berikut ini.

Program 3.11. Konstruktor copy array satu dimensi


1. template<class T>
2. Array1D<T>::Array1D(const Array1D<T>& v)
3. {
4. size = v.size;
5. element = new T[size];
6. for (int i = 0; i < size; i++)
7. element[i] = v.element[i];
8. }

Perlu diperhatikan bahwa yang aktif pada copy konstruktor di atas adalah
pointer this. Ukurannya disalin dari objek v (4), kemudian dipesan memori sebanyak
ukurannya (5). Proses penyalinan elemen dilakukan elemen demi elemen (6 dan 7).
Kita juga dapat mengakses elemen tertentu dari array menggunakan operator []
berikut ini.

Program 3.12. Overloading operator [ ], yaitu


mengembalikan elemen array pada posisi ke-i

Bab 4 Array halaman 52


1. template<class T>
2. T& Array1D<T>::operator[](int i) const
3. {
4. return element[i];
5. }

Kita dapat membuat operator penugasan khusus array dengan cara meng-
overload operator =. Untuk itu dibuat dengan cara sebagai berikut :

Program 3.13. Overload operator penugasan =.


1. template<class T>
2. Array1D<T>& Array1D<T>::operator=(const Array1D<T>& v)
3. {
4. if (this != &v) {
5. size = v.size;
6. delete [] element;
7. element = new T[size];
8. for (int i = 0; i < size; i++)
9. element[i] = v.element[i];
10. }
11. return *this;
12. }

Operator = pada dasarnya berfungsi untuk menyalin semua elemen dari array v
(2) ke array yang lain, dalam hal ini diwakili this. Jika v bukan dirinya sendiri (4)
maka proses penyalinan akan dilaksanakan. Langkah pertama, ukuran dari v disalin
(5). Elemen lama (bila ada) dibebaskan (6). Kemudian dipesan memori sebesar
ukuran size untuk array element (dalam hal ini yang ditunjuk pointer this) (7).
Setelah itu baru disalin elemen demi elemen (8) setiap elemen array v ke elemen
array this (9). Pointer this dikembalikan (11).
Demikian pula apabila dikehendaki meng-overload operator +, dapat
dilakukan dengan cara sebagai berikut :

Program 3.14. Overload operator +, mengembalikan array w


1. template<class T>
2. Array1D<T> Array1D<T>::operator+(const Array1D<T>& v) const
3. {

Bab 4 Array halaman 53


4. Array1D<T> w(size);
5. for (int i = 0; i < size; i++)
6. w.element[i] = element[i] + v.element[i];
7. return w;
8. }

Untuk mengetahui cara kerja operator overload +, dimisalkan kita punya


pernyataan :
z = x + y;
Ketika pernyataan dieksekusi, x akan mewakili objek saat ini yang akan mengakses
semua data member, sedangkan y akan mewakili v. Harga yang dikembalikan, yaitu
w kemudian di-assign ke z. Operasi penjumlahan akan dilakukan pada setiap elemen
(5 dan 6).
Dengan cara yang sama, kita peroleh overloaded operator untuk operator –
berikut ini :
Program 3.15. Overload operator -, mengembalikan array w
1. template<class T>
2. Array1D<T> Array1D<T>::operator-(const Array1D<T>& v) const
3. {
4. Array1D<T> w(size);
5. for (int i = 0; i < size; i++)
6. w.element[i] = element[i] - v.element[i];
7. return w;
8. }

Perilaku operator overload – serupa dengan operator overload +. Hanya


operasi penjumlahan diganti dengan operasi pengurangan (6).

Program 3.16. Overload operator unari -, mengembalikan array w


1. template<class T>
2. Array1D<T> Array1D<T>::operator-() const
3. {
4. Array1D<T> w(size);
5. for (int i = 0; i < size; i++)
6. w.element[i] = -element[i];
7. return w;
8. }

Bab 4 Array halaman 54


Operator overload unari – serupa dengan dua operator overload terdahulu,
kecuali setiap elemen dinegasikan (6).
Operator overload * berikut digunakan untuk menghitung hasil perkalian dari
setiap elemen indeks ke-i dengan elemen indeks i array lain.

Program 3.17. Overload operator *, mengembalikan array w


1. template<class T>
2. Array1D<T> Array1D<T>::operator*(const Array1D<T>& v) const
3. {
4. Array1D<T> w(size);
5. for (int i = 0; i < size; i++)
6. w.element[i] = element[i] * v.element[i];
7. return w;
8. }

Perilaku operator overload * serupa dengan operator overload +. Hanya


operasi penjumlahan diganti dengan operasi perkalian (6).
Bila kita ingin menambah setiap elemen array dengan suatu bilangan tertentu,
kita buat overload operator += dengan cara berikut ini.

Program 3.18. Menambahkan x pada setiap elemen


1. template<class T>
2. Array1D<T>& Array1D<T>::operator+=(const T& x)
3. {
4. for (int i = 0; i < size; i++)
5. element[i] += x;
6. return *this;
7. }

Untuk mencetak array kita membutuhkan overload operator cout. Caranya


adalah sebagai berikut :

Program 3.19. Meletakkan setiap elemen x ke dalam stream out.


1. template<class T>
2. ostream& operator<<(ostream& out, const Array1D<T>& x)
3. {

Bab 4 Array halaman 55


4. for (int i = 0; i < x.size; i++)
5. out << x.element[i] << " ";
6. return out;
7. }

Stream out akan digunakan untuk mencetak setiap elemen array (5).

Dalam pengertian array, oleh karena array termasuk struktur data statis,
tidaklah lazim untuk mengubah banyaknya memori yang dipesan oleh suatu array.
Namun untuk TDA array kita ini, kita bisa mengubahnya dengan cara sebagai
berikut :

Program 3.20. Mengubah ukuran size dengan sz. Tidak menyalin


elemen array untuk ukuran yang baru
1. template<class T>
2. Array1D<T>& Array1D<T>::ReSize(int sz)
3. {
4. delete [] element;
5. size = sz;
6. element = new T [size];
7. return *this;
8. }

Untuk menguji TDA array di atas, dapat menggunakan fungsi main berikut ini:

Program 3.21. Fungsi main untuk mencoba TAD array satu dimensi
1. #include <iostream.h>
2. #include "array1d.h"
3. void main(void)
4. {
5. Array1D<int> X(10), Y, Z;
6. for (int i=0; i < 10; i++) X[i] = i;
7. cout << "X[3] = " << X[3] << endl;
8. cout << "X is " << X << endl;
9. Y = X;
10. cout << "Y is " << Y << endl;
11. X += 2;
12. cout << "X incremented by 2 is " << X << endl;
13. Z = (Y + X) * Y;
14. cout << "(Y + X) * Y is " << Z << endl;
15. cout << "-(Y + X) * Y is " << -Z << endl;

Bab 4 Array halaman 56


16. }

D. Tipe Data Abstrak Array Dua Dimensi


Kelas Array2D berikut ini sebenarnya data membernya menggunakan kelas
Array1D.

Program 3.22. Kelas Array Dua Dimensi Array2D


1. template<class T>
2. class Array2D {
3. friend ostream& operator<< (ostream&, const Array2D<T>&);
4. public:
5. Array2D(int r = 0, int c = 0);
6. Array2D(const Array2D<T>& m); // copy constructor
7. ~Array2D() {delete [] row;}
8. int Rows() const {return rows;}
9. int Columns() const {return cols;}
10. Array1D<T>& operator[](int i) const;
11. Array2D<T>& operator=(const Array2D<T>& m);
12. Array2D<T> operator+() const; // unary +
13. Array2D<T> operator+(const Array2D<T>& m) const;
14. Array2D<T> operator-() const; // unary minus
15. Array2D<T> operator-(const Array2D<T>& m) const;
16. Array2D<T> operator*(const Array2D<T>& m) const;
17. Array2D<T>& operator+=(const T& x);
18. private:
19. int rows, cols;
20. Array1D<T> *row;
21. };

Program 3.23. Konstruktor Array2D


1. template<class T>
2. Array2D<T>::Array2D(int r, int c)
3. { rows = r;
4. cols = c;
5. row = new Array1D<T> [r];
6. for (int i = 0; i < r; i++)
7. row[i].ReSize(c);
8. }

Program 3.24. Copy constructor Array2D


1. template<class T>

Bab 4 Array halaman 57


2. Array2D<T>::Array2D(const Array2D<T>& m)
3. { rows = m.rows;
4. cols = m.cols;
5. row = new Array1D<T> [rows];
6. for (int i = 0; i < rows; i++)
7. row[i] = m.row[i];
8. }

Program 3.25. Operator Overloading Penugasan =


1. template<class T>
2. Array2D<T>& Array2D<T>::operator=(const Array2D<T>& m)
3. {// Penugasan. (*this) = m.
4. if (this != &m) {
5. delete [] row;
6. rows = m.rows; cols = m.cols;
7. row = new Array1D<T> [rows];
8. for (int i = 0; i < rows; i++)
9. row[i] = m.row[i];
10. }
11. return *this;
12. }

Program 3.26. Operator Overloading +


1. template<class T>
2. Array2D<T> Array2D<T>::operator+(const Array2D<T>& m) const
3. {
4. if (rows != m.rows || cols != m.cols) throw SizeMismatch();
5. Array2D<T> w(rows,cols);
6. for (int i = 0; i < rows; i++)
7. w.row[i] = row[i] + m.row[i];
8. return w;
9. }

Program 3.27. Operator Overloading -


1. template<class T>
2. Array2D<T> Array2D<T>::operator-(const Array2D<T>& m) const
3. {
4. if (rows != m.rows || cols != m.cols) throw SizeMismatch();
5. Array2D<T> w(rows,cols);
6. for (int i = 0; i < rows; i++)
7. w.row[i] = row[i] - m.row[i];

Bab 4 Array halaman 58


8. return w;
9. }

Program 3.28. Operator Overloading Unary -


1. template<class T>
2. Array2D<T> Array2D<T>::operator-() const
3. {
4. Array2D<T> w(rows, cols);
5. for (int i = 0; i < rows; i++)
6. w.row[i] = -row[i];
7. return w;
8. }

Program 3.29. Operator Overloading *


1. template<class T>
2. Array2D<T> Array2D<T>::operator*(const Array2D<T>& m) const
3. {
4. if (cols != m.rows) throw SizeMismatch();
5. Array2D<T> w(rows, m.cols);
6. for (int i = 0; i < rows; i++)
7. for (int j = 0; j < m.cols; j++) {
8. T sum = (*this)[i][0] * m[0][j];
9. for (int k = 1; k < cols; k++)
10. sum += (*this)[i][k] * m[k][j];
11. w[i][j] = sum;
12. }
13. return w;
14. }

Program 3.30. Operator Overloading +=


1. template<class T>
2. Array2D<T>& Array2D<T>::operator+=(const T& x)
3. {
4. for (int i = 0; i < rows; i++)
5. row[i] += x;
6. return *this;
7. }

Program 3.31. Operator Overloading <<


1. template<class T>

Bab 4 Array halaman 59


2. ostream& operator<<(ostream& out, const Array2D<T>& x)
3. {
4. for (int i = 0; i < x.rows; i++)
5. out << x.row[i] << endl;
6. return out;
7. }

Program 3.32. Fungsi main untuk mencoba kelas Array2D


1. #include <iostream.h>
2. #include "array2d.h"
3.
4. void main(void)
5. {
6. try {
7. int i, j;
8. Array2D<int> X(3,2), Y, Z;
9. for (i = 0; i < 3; i++)
10. for (j = 0; j < 2; j++) X[i][j] = 2*i + j;
11. cout << "X[2][1] = " << X[2][1] << endl;
12. cout << "X is" << endl; cout << X << endl;
13. Y = X;
14. cout << "Y is" << endl; cout << Y << endl;
15. X += 2;
16. cout << "X incremented by 2 is" << endl; cout << X << endl;
17. Z = Y + X;
18. cout << "Y + X is" << endl; cout << Z << endl;
19. cout << "-(Y + X) is" << endl; cout << -Z << endl;
20. Array2D<int> W(2,3);
21. for (i = 0; i < 2; i++)
22. for (j = 0; j < 3; j++) W[i][j] = i + j;
23. cout << "W is" << endl; cout << W << endl;
24. Z = Y * W;
25. cout << "Y * W is" << endl; cout << Z << endl;
26. }
27. catch (...) { cerr << "An exception has occurred" << endl;}
28. }

Latihan
Di bawah ini diberikan kelas Matrix beserta implementasinya. Pelajarilah
kelas Matrix, meliputi :
1. konstruktor

Bab 4 Array halaman 60


2. copy constructor

3. destruktor

4. operator overloading

1. #include "bool.h"
2. template<class T>
3. class Matrix {
4. friend ostream& operator<<(ostream&, const Matrix<T>&);
5. public:
6. Matrix(int r = 0, int c = 0);
7. Matrix(const Matrix<T>& m); // copy constructor
8. ~Matrix() {delete [] element;}
9. int Rows() const {return rows;}
10. int Columns() const {return cols;}
11. T& operator()(int i, int j) const;
12. Matrix<T>& operator=(const Matrix<T>& m);
13. Matrix<T> operator+() const; // unary +
14. Matrix<T> operator+(const Matrix<T>& m) const;
15. Matrix<T> operator-() const; // unary minus
16. Matrix<T> operator-(const Matrix<T>& m) const;
17. Matrix<T> operator*(const Matrix<T>& m) const;
18. Matrix<T>& operator+=(const T& x);
19. private:
20. int rows, cols;
21. T *element;
22. };
23. template<class T>
24. Matrix<T>::Matrix(int r, int c)
25. {
26. rows = r; cols = c;
27. element = new T [r * c];
28. }

29. template<class T>


30. Matrix<T>::Matrix(const Matrix<T>& m)
31. {
32. rows = m.rows; cols = m.cols;
33. element = new T [rows * cols];
34. for (int i = 0; i < rows * cols; i++)
35. element[i] = m.element[i];

Bab 4 Array halaman 61


36. }
37. template<class T>
38. Matrix<T>& Matrix<T>::operator=(const Matrix<T>& m)
39. {
40. if (this != &m) {// do not copy to self
41. delete [] element;
42. rows = m.rows; cols = m.cols;
43. element = new T [rows * cols];
44. for (int i = 0; i < rows * cols; i++)
45. element[i] = m.element[i];
46. }
47. return *this;
48. }
49. template<class T>
50. T& Matrix<T>::operator()(int i, int j) const
51. {
52. return element[(i - 1) * cols + j - 1];
53. }
54. template<class T>
55. Matrix<T> Matrix<T>::operator+(const Matrix<T>& m) const
56. {
57. Matrix<T> w(rows, cols);
58. for (int i = 0; i < rows * cols; i++)
59. w.element[i] = element[i] + m.element[i];
60. return w;
61. }
62. template<class T>
63. Matrix<T> Matrix<T>::operator-(const Matrix<T>& m) const
64. {
65. Matrix<T> w(rows, cols);
66. for (int i = 0; i < rows * cols; i++)
67. w.element[i] = element[i] - m.element[i];
68. return w;
69. }
70. template<class T>
71. Matrix<T> Matrix<T>::operator-() const

Bab 4 Array halaman 62


72. {
73. Matrix<T> w(rows, cols);
74. for (int i = 0; i < rows * cols; i++)
75. w.element[i] = -element[i];
76. return w;
77. }
78. template<class T>
79. Matrix<T> Matrix<T>::operator*(const Matrix<T>& m) const
80. {
81. Matrix<T> w(rows, m.cols);
82. int ct = 0, cm = 0, cw = 0;
83. for (int i = 1; i <= rows; i++) {
84. for (int j = 1; j <= m.cols; j++) {
85. T sum = element[ct] * m.element[cm];
86. for (int k = 2; k <= cols; k++) {
87. ct++;
88. cm += m.cols;
89. sum += element[ct] * m.element[cm];
90. }
91. w.element[cw++] = sum; // save w(i,j)
92. ct -= cols - 1;
93. cm = j;
94. }
95. ct += cols;
96. cm = 0;
97. }
98. return w;
99. }
100. template<class T>
101. Matrix<T>& Matrix<T>::operator+=(const T& x)
102. {
103. for (int i = 0; i < rows * cols; i++)
104. element[i] += x;
105. return *this;
106. }
107. template<class T>
108. ostream& operator<<(ostream& out, const Matrix<T>& x)
109. {

Bab 4 Array halaman 63


110. int k = 0;
111. for (int i = 0; i < x.rows; i++) {
112. for (int j = 0; j < x.cols; j++)
113. out << x.element[k++] << " ";
114. out << endl;}
115. return out;
116. }

Bab 4 Array halaman 64


SKENARIO PERKULIAHAN MINGGU 5

Persiapan [50 menit]


01. Mahasiswa mengerjakan Pretest Praktikum
02. Mahasiswa mempelajari Representasi Data Linear List
03. Mahasiswa membuat contoh Representasi Data Linear List
04. Catatan :
a. Boleh belajar bersama kelompok masing-masing
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]


00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-
masing
01. Dosen membuka perkuliahan
02. Dosen memberikan contoh Representasi Data Linear List
03. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
04. Dosen menjelaskan pembuatan Representasi Data Linear List
05. Mahasiswa mengikuti dengan compilernya masing-masing
06. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]


01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya
masing-masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]


01. Dosen memberikan rangkuman materi kuliah minggu ini
02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 5 Representasi Data halaman 65


Bab V

Representasi Data

Tujuan Pembelajaran
1. mahasiswa memahami beberapa konsep representasi data

2. mahasiswa dapat menerapkan konsep representasi data dalam bahasa


pemrograman C++

A. Pendahuluan

Ada beberapa metode representasi data, yaitu didasarkan rumus, linked


(didasarkan pointer), pengalamatan tak langsung dan pointer tersimulasi.
Representasi data berdasarkan rumus menggunakan rumus matematika untuk
menentukan alamat memori untuk menyimpan setiap elemen list. Pada representasi
data linked (pointer), elemen list disimpan pada alamat tertentu dari lokasi memori.
Setiap elemen secara eksplisit mempunyai rantai (link) untuk menunjuk ke elemen
berikutnya.

B. Representasi Data Didasarkan Rumus

Berikut ini akan dikembangkan kelas LinearList menggunakan representasi


data berdasarkan rumus.

Program 4.1. kelas LinearList menggunakan


representasi data berdasarkan rumus
1. template<class T>
2. class LinearList {
3. public:
4. LinearList(int MaxListSize = 10);
5. ~LinearList() {delete [] element;}
6. bool IsEmpty() const {return length == 0;}
7. int Length() const {return length;}
8. bool Find(int k, T& x) const;
9. int Search(const T& x) const;
10. LinearList<T>& Delete(int k, T& x);

Bab 5 Representasi Data halaman 66


11. LinearList<T>& Insert(int k, const T& x);
12. void Output(ostream& out) const;
13. private:
14. int length;
15. int MaxSize;
16. T *element;
17. };

Konstruktor dari kelas LinearList (4) memberikan ukuran maksimum dari


linier list sebesar MaxListSize = 10. Destruktor akan menghapus setiap elemen dari
linear list (5). Method IsEmpty() digunakan untuk mengecek apakah linear list
kosong atau tidak (6) dengan cara menguji apakah panjangnya = 0 atau tidak. Jika
panjang linear list sama dengan 0, true dikembalikan, false jika tidak. Method
Length() mengembalikan panjang dari linear list (7). Dalam hal ini, member data
length langsung diakses (14).
Method Find(int k, T& x) digunakan untuk melihat elemen ke-k yang di-
assign pada x (8). Method Search(const T& x) mengembalikan posisi (letak) dari
elemen x (9). Method Delete(int k, T& x) digunakan untuk menghapus elemen ke-k
dari linear list dan elemen yang dihapus di-assign pada x (10). Method Insert(int k,
const T& x) digunakan untuk menyisipkan elemen x setelah elemen ke-k. Method
Output(ostream& out) digunakan untuk meletakkan linear list dalam stream out. Cara
kerja masing-masing method akan dijelaskan tersendiri.

Program 4.2. Konstruktor formula-based linear list.


1. template<class T>
2. LinearList<T>::LinearList(int MaxListSize)
3. {
4. MaxSize = MaxListSize;
5. element = new T[MaxSize];
6. length = 0;
7. }

Bab 5 Representasi Data halaman 67


Harga awal dari konstruktor di-assign ke private data member MaxSize (4).
Array dinamis element sebanyak MaxSize yang bertipe T (5). Oleh karena baru
diciptakan maka panjang linier list yang dibuat masih 0 (6).

Program 4.3. Method Find digunakan untuk


mengembalikan elemen ke-k yaitu x
1. template<class T>
2. bool LinearList<T>::Find(int k, T& x) const
3. {
4. if (k < 1 || k > length) return false;
5. x = element[k - 1];
6. return true;
7. }

Jika nilai k di bawah 1 atau melebihi panjang linear list, jelas tidak dapat
ditemukan elemen yang dicari, false dikembalikan (4). x akan di-assign oleh elemen
ke-(k-1) dan true dikembalikan (5).

Program 4.4. Method Search untuk mencari x pada element.


Bila ditemukan, posisi dari x dikembalikan, 0 jika tidak
1. template<class T>
2. int LinearList<T>::Search(const T& x) const
3. {
4. for (int i = 0; i < length; i++)
5. if (element[i] == x) return ++i;
6. return 0;
7. }

Elemen x akan dicari dengan menggunakan cara pencarian linier, yaitu akan
dibandingkan dengan setiap elemen linear list dari awal sampai akhir (4) atau sampai
pada posisi di mana elemen tersebut ditemukan. Jika ditemukan posisi ke-i akan
dikembalikan (5). Jika sampai elemen terakhir tidak ditemukan, 0 (atau false) akan
dikembalikan (6).

Bab 5 Representasi Data halaman 68


Program 4.5. Method Delete digunakan untuk menghapus
elemen ke-k, elemen yang dihapus adalah x
1. template<class T>
2. LinearList<T>& LinearList<T>::Delete(int k, T& x)
3. {
4. if (Find(k, x)) {// move elements k+1, ..., down
5. for (int i = k; i < length; i++)
6. element[i-1] = element[i];
7. length--;
8. return *this;
9. }
10. }

Elemen ke-k akan dihapus dari linear list. Untuk itu elemen ke-k dicari lebih dulu (4)
dan di-assign ke x. Kemudian elemen dari posisi k sampai akhir digeser satu posisi di
depan (5 sampai 7). Pointer ke linear list dengan elemen yang telah dihapus
dikembalikan (8).

Program 4.6. Menyisipkan elemen x sesudah elemen ke-k


1. template<class T>
2. LinearList<T>& LinearList<T>::Insert(int k, const T& x)
3. {
4. for (int i = length-1; i >= k; i--)
5. element[i+1] = element[i];
6. element[k] = x;
7. length++;
8. return *this;
9. }

Elemen x akan disisipkan pada posisi ke-k (6). Untuk itu, setiap elemen akan
digeser ke kanan dari posisi k sampai dengan akhir elemen (4 dan 5). Panjang linear
list akan bertambah 1 (7). Pointer yang menunjuk linear list dengan elemen yang
telah ditambahkan dikembalikan (8).

Bab 5 Representasi Data halaman 69


Program 4.7. Stream out digunakan untuk mencetak element.
1. template<class T>
2. void LinearList<T>::Output(ostream& out) const
3. {
4. for (int i = 0; i < length; i++)
5. out << element[i] << " ";
6. }

Setiap element akan dicetak (5) dari awal sampai akhir (4).

Program 4.8. Operator overloading <<


1. template <class T>
2. ostream& operator<<(ostream& out, const LinearList<T>& x)
3. {x.Output(out); return out;}

Untuk menguji-coba kelas LinearList digunakan fungsi main berikut ini.

Program 4.9. Fungsi main untuk kelas LinearList


1. #include <iostream.h>
2. #include "llist.h"
3.
4. void main(void)
5. {
6. LinearList<int> L(5);
7. cout << "Length = " << L.Length() << endl;
8. cout << "IsEmpty = " << L.IsEmpty() << endl;
9. L.Insert(0,2).Insert(1,6);
10. cout << "List is " << L << endl;
11. cout << "IsEmpty = " << L.IsEmpty() << endl;
12. int z;
13. L.Find(1,z);
14. cout << "First element is " << z << endl;
15. cout << "Length = " << L.Length() << endl;
16. L.Delete(1,z);
17. cout << "Deleted element is " << z << endl;
18. cout << "List is " << L << endl;
19. }

Linear list L dibuat bertipe int dan mempunyai elemen sebanyak 5 (6).
Panjang dari linear list awalnya adalah 0 (7). Dilakukan pengecekan apakah linear
list

Bab 5 Representasi Data halaman 70


kosong atau tidak (8), dan ternyata benar (bernilai 1). Kemudian disisipkan dua
elemen yaitu 2 dan 6. Elemen 2 pada posisi ke-1 (disisipkan setelah posisi ke-0),
elemen 6 pada posisi ke-2 (disisipkan setelah posisi ke-1) (9). Isi linear list L dicetak
(10) berisi elemen 2 dan 6. Dicek lagi, ternyata linear list L tidak kosong lagi
(bernilai 0) (11). Dicari elemen ke-1 (13) dan ditemukan elemen 2 (14). Panjang
linear list L adalah 2 (15). Elemen ke-1 dihapus (16). Elemen yang dihapus adalah 2
(17), sehingga elemen yang tersisa dari linear list L adalah 6 (18). Output dari
program di atas disajikan pada tabel berikut ini :

Ouput :

Length = 0
IsEmpty = 1
List is 2 6
IsEmpty = 0
First element is 2
Length = 2
Deleted element is 2
List is 6

C. Representasi Data Linked


Dalam representasi data linked, setiap elemen instan dari objek data
direpresentasikan dalam sebuah simpul atau node. Setiap node mempunyai eksplisit
link (pointer) yang digunakan untuk menunjuk elemen berikutnya. Untuk
merepresentasikan list linier sebagai rantai, kita gunakan kelas ChainNode dan
Chain.

Program 4.10. Kelas ChainNode yang akan disimpan pada file cnode.h
1. template <class T> class Chain;
2. template <class T> class ChainIterator;
3. template <class T> class KeyedChain;
4. template <class T> class LinkedStack;
5.
6. template <class T>
7. class ChainNode {
8. friend Chain<T>;
9. friend ChainIterator<T>;

Bab 5 Representasi Data halaman 71


10. friend KeyedChain<T>;
11. friend LinkedStack<T>;
12. private:
13. T data;
14. ChainNode<T> *link;
15. };

Kelas ChainNode mempunyai dua data member yaitu data untuk menyimpan data,
dan link untuk menunjuk (menyambung) elemen berikutnya.

Program 4.11. Kelas Chain yang menggunakan kelas


ChainNode disimpan pada file chain.h
1. #include "cnode.h"
2. template <class T> class ChainIterator;
3. template<class T>
4. class Chain {
5. friend ChainIterator<T>;
6. public:
7. Chain() {first = 0;}
8. ~Chain();
9. bool IsEmpty() const {return first == 0;}
10. int Length() const;
11. bool Find(int k, T& x) const;
12. int Search(const T& x) const;
13. Chain<T>& Delete(int k, T& x);
14. Chain<T>& Insert(int k, const T& x);
15. void Output(ostream& out) const;
16. private:
17. ChainNode<T> *first;
18. };

Private data member hanyalah first (17), yaitu pointer yang menunjuk elemen
pertama dari linear list. Konstruktor melakukan set awal first tidak menunjuk
kemanapun (sama dengan 0/NULL (7)). Methodnya tidak berbeda dengan model
terdahulu.

Bab 5 Representasi Data halaman 72


Program 4.12. Destruktor kelas Chain. Menghapus semua
node pada chain.
1. template<class T>
2. Chain<T>::~Chain()
3. {
4. ChainNode<T> *next;
5. while (first) {
6. next = first->link;
7. delete first;
8. first = next;
9. }
10. }

Cara menghapus linear list adalah sebagai berikut : loop while berjalan sampai
first bernilai 0 (false) (5). next digunakan untuk menunjuk elemen berikutnya dari
first (6). Setelah berpindah ke node berikutnya, pointer first dihapus (7). Dengan
demikian memori dibebaskan. first memegang kembali node berikutnya yang
ditunjuk next (8), dan ini dilakukan berulang-ulang sampai seluruh node terhapus
dan first bernilai 0.

Program 4.13. Method Length untuk menghitung


banyaknya elemen pada linear list.
1. template<class T>
2. int Chain<T>::Length() const
3. {
4. ChainNode<T> *current = first;
5. int len = 0;
6. while (current) {
7. len++;
8. current = current->link;
9. }
10. return len;
11. }

current digunakan sebagai pointer bantu yang “diminta” untuk jalan-jalan.


Pertama, current diset menunjuk pada first (4). Counter panjang rantai len diberi
nilai awal 0 (5). Loop while berjalan sampai current bernilai 0 (6). Setiap kali loop,

Bab 5 Representasi Data halaman 73


len bertambah 1 (7). Kemudian current menunjuk elemen berikutnya (8). Panjang
rantai len dikembalikan (10).

Program 4.14. Elemen ke-k di-set ke x, jika ada.


1. template<class T>
2. bool Chain<T>::Find(int k, T& x) const
3. {
4. if (k < 1) return false;
5. ChainNode<T> *current = first;
6. int index = 1;
7. while (index < k && current) {
8. current = current->link;
9. index++;
10. }
11. if (current) {x = current->data;
12. return true;}
13. return false;
14. }

Tujuan method Find(int k, T& x) adalah meng-assign elemen ke-k pada x.


Pertama, current menunjuk linear list yang ditunjuk first (5). Indeks index saat ini
sama dengan 1 (6). Berangkat dari awal (index=1) sampai k-1 dan current belum
NULL (akhir), current jalan-jalan (8), dan index selalu bertambah 1 (9).
Kondisional if (11) terjadi pada posisi k (current tidak bernilai 0) dan data saat itu
di-assign pada x, dan true dikembalikan. Namun bila sampai NULL (akhir elemen)
walaupun current belum sampai nilai k, berarti tidak ada elemen ke-k, false
dikembalikan (13).

Program 4.15. Mengembalikan letak (posisi) elemen x


1. template<class T>
2. int Chain<T>::Search(const T& x) const
3. {
4. ChainNode<T> *current = first;
5. int index = 1; // index of current
6. while (current && current->data != x) {
7. current = current->link;
8. index++;
9. }
10. if (current) return index;

Bab 5 Representasi Data halaman 74


11. return 0;
12. }

Berbeda dengan method Find, method Search(const T& x) digunakan untuk


mencari elemen x dalam linear list. Proses pencarian dimulai dari awal (4) elemen
demi elemen (7) dan pembandingan dilakukan (6) sampai akhir elemen (current
bernilai 0) atau x tidak sama dengan data saat itu. Setiap kali melangkah ke elemen
berikutnya, index bertambah 1 (8). Bila x ada dan ditemukan, loop while berhenti
selanjutnya kondisional if akan dijalankan, nilai index dikembalikan, yaitu posisi di
mana x ditemukan. Jika tidak 0 dikembalikan (11).

Program 4.16. Set elemen ke-k pada x, kemudian hapus


1. template<class T>
2. Chain<T>& Chain<T>::Delete(int k, T& x)
3. {
4. ChainNode<T> *p = first;
5. if (k == 1)
6. first = first->link;
7. else {
8. ChainNode<T> *q = first;
9. for (int index = 1; index < k - 1 && q; index++)
10. q = q->link;
11. p = q->link; // k'th
12. q->link = p->link;}
13. x = p->data;
14. delete p;
15. return *this;
16. }

Pointer p menunjuk elemen yang ditunjuk first (4). Jika elemen yang dihapus
adalah elemen pertama (5) first menunjuk elemen berikutnya (6). Jika tidak (7)
pointer q (awalnya menunjuk elemen pertama seperti yang ditunjuk first (8))
digunakan untuk jalan-jalan bergeser (10) dari elemen pertama (index = 1) sampai
dengan elemen ke-(k-1). Kemudian p menunjuk elemen ke-k (11). Cara menghapus
elemen ke-k adalah dengan cara melompat link elemen ke-(k-1) menunjuk elemen
ke-

Bab 5 Representasi Data halaman 75


(k+1) (12). Elemen yang dihapus di-assign ke x (13). Memori kemudian dibebaskan
(14), dan fungsi mengembalikan linear list yang telah dihapus elemen ke-k nya (15).

Program 4.17. Menyisipkan elemen x sesudah posisi ke-k


1. template<class T>
2. Chain<T>& Chain<T>::Insert(int k, const T& x)
3. {
4. ChainNode<T> *p = first;
5. for (int index = 1; index < k && p; index++)
6. p = p->link;
7. ChainNode<T> *y = new ChainNode<T>;
8. y->data = x;
9. if (k) {
10. y->link = p->link;
11. p->link = y;}
12. else {
13. y->link = first;
14. first = y;}
15. return *this;
16. }

Untuk kasus k tidak pada posisi pertama, gambar logiknya adalah sebagai berikut
Kondisi awal :
p p->link

first
‘B’’ ‘C’’ ‘E’’

posisi ke-(k-1) posisi ke-k


y
‘D’’

(10) p p->link

first
‘B’’ ‘C’’ ‘E’’

y
‘D’’

Untuk kasus k pada posisi pertama, gambar logiknya adalah sebagai berikut :

Kondisi awal :

Bab 5 Representasi Data halaman 76


p

y first
‘B’’ ‘C’’ ‘E’’

posisi ke-(1) posisi ke-2

(13) p p->link

y first
‘B’’ ‘C’’ ‘E’’

(14) first p p->link

y
‘B’’ ‘C’’ ‘E’’

Pointer p menunjuk elemen yang ditunjuk first (4). Pointer p jalan-jalan (6)
dari elemen ke-1 sampai dengan elemen ke-(k-1) (5). Dibuat node baru y (7)
kemudian data membernya di-assign elemen x (8). Jika posisi elemen ke-k bukan
posisi awal (9) link dari y menunjuk elemen yang berada di posisi ke-k (10). Elemen
yang baru akan disisipkan pada posisi ke-k (11). Jika posisi elemen ke-k pada
awal
(12) maka link pointer y menunjuk pada first (13) lalu first akan menunjuk elemen
pertama yaitu elemen yang ditunjuk y (14). Fungsi mengembalikan linear list yang
telah disisipi elemen baru.

Program 4.18. Fungsi Output yang akan digunakan untuk


operator overloading
1. template<class T>
2. void Chain<T>::Output(ostream& out) const
3. { ChainNode<T> *current;
4. for (current = first; current; current = current->link)
5. out << current->data << " ";
6. }
Operator overloading di bawah ini, menggunakan method Output untuk
implementasinya.
Program 4.19. Operator overloading << untuk kelas Chain
1. template <class T>
2. ostream& operator<<(ostream& out, const Chain<T>& x)

Bab 5 Representasi Data halaman 77


3. {x.Output(out); return out;}

Fungsi main untuk penggunaan kelas Chain diberikan berikut ini.

Program 4.20. Fungsi main untuk menguji kelas Chain


1. #include <iostream.h>
2. #include "chain.h"
3. void main(void)
4. {
5. Chain<int> L;
6. cout << "Length = " << L.Length() << endl;
7. cout << "IsEmpty = " << L.IsEmpty() << endl;
8. L.Insert(0,2).Insert(1,6);
9. cout << "List is " << L << endl;
10. cout << "IsEmpty = " << L.IsEmpty() << endl;
11. int z;
12. L.Find(1,z);
13. cout << "First element is " << z << endl;
14. cout << "Length = " << L.Length() << endl;
15. L.Delete(1,z);
16. cout << "Deleted element is " << z << endl;
17. cout << "List is " << L << endl;
18. }

D. Perluasan kelas chain : echain

Fungsi main untuk mencoba kelas Chain yang


diperluas operasinya
1. #include <iostream.h>
2. #include "echain.h"
3. void main(void)
4. {
5. Chain<int> L;
6. L.Insert(0,2).Insert(1,6);
7. cout << "List is " << L << endl;
8. L.Append(8);
9. cout << "After appending 8, list is " << L << endl;
10. L.Erase();
11. cout << "After erase, list is " << L << endl;
12. L.Append(1).Append(2).Append(3).Append(4);
13. cout << "List is " << L << endl;

Bab 5 Representasi Data halaman 78


14. L.Zero();
15. cout << "After zero, list is " << L << endl;
16. }

Kelas Chain yang diperluas (Extended) disimpan


pada file echain.h
1. template <class T> class ChainIterator;
2. template<class T>
3. class Chain {
4. friend ChainIterator<T>;
5. public:
6. Chain() {first = 0;}
7. ~Chain() {Erase();}
8. bool IsEmpty() const {return first == 0;}
9. int Length() const;
10. bool Find(int k, T& x) const;
11. int Search(const T& x) const;
12. Chain<T>& Delete(int k, T& x);
13. Chain<T>& Insert(int k, const T& x);
14. void Zero() {first = 0;}
15. void Erase(); // delete all nodes
16. Chain<T>& Append(const T& x);
17. void Output(ostream& out) const;
18. private:
19. ChainNode<T> *first, // pointer to first node
20. *last; // pointer to last node
21. };

Member data ada dua yaitu first yang digunakan untuk menunjuk elemen
pertama (20) dan menunjuk elemen terakhir (21).

// Chain destructor. Delete all nodes in chain.


1. template<class T>
2. void Chain<T>::Erase()
3. {
4. ChainNode<T> *next;
5. while (first) {
6. next = first->link;
7. delete first;
8. first = next;
9. }

Bab 5 Representasi Data halaman 79


10. }

Perulangan dilakukan pada pointer first (5) sampai pointer first menunjuk ke 0
(NULL). Pointer next digunakan untuk menunjuk elemen berikutnya (6). Memori
dibebaskan (7), first menunjuk elemen berikutnya yang akan dihapus (8).

1. template<class T>
2. Chain<T>& Chain<T>::Delete(int k, T& x)
3. {// Set x to the k'th element and delete it.
4. // p will eventually point to k'th node
5. ChainNode<T> *p = first;
6. // move p to k'th & remove from chain
7. if (k == 1) // p already at k'th
8. first = first->link; // remove
9. else { // use q to get to k-1'st
10. ChainNode<T> *q = first;
11. for (int index = 1; index < k - 1 && q; index++)
12. q = q->link;
13. p = q->link; // k'th
14. if (p == last) last = q;
15. q->link = p->link;} // remove from chain
16. // save k'th element and free node p
17. x = p->data;
18. delete p;
19. return *this;
20. }

1. template<class T>
2. Chain<T>& Chain<T>::Insert(int k, const T& x)
3. {// Insert x after the k'th element.
4. // p will eventually point to k'th node
5. ChainNode<T> *p = first;
6. for (int index = 1; index < k && p; index++)
7. p = p->link;
8. // insert
9. ChainNode<T> *y = new ChainNode<T>;
10. y->data = x;
11. if (k) {// insert after p
12. y->link = p->link;
13. p->link = y;}

Bab 5 Representasi Data halaman 80


14. else {// insert as first element
15. y->link = first;
16. first = y;}
17. if (!y->link) last = y; // new last element
18. return *this;
19. }

// Add at right end.


1. template<class T>
2. Chain<T>& Chain<T>::Append(const T& x)
3. {
4. ChainNode<T> *y = new ChainNode<T>;
5. y->data = x;
6. y->link = 0;
7. if (first) {// chain is not empty
8. last->link = y;
9. last = y;}
10. else // chain is empty
11. first = last = y;
12. return *this;
13. }

Gambar logiknya untuk kasus menambah elemen bila first menunjuk linear list yang
tidak kosong : misalkan nilai x adalah karakter ‘D’’.
Kondisi awal :
last

first
‘B’’ ‘C’’

{5 dan 6} y
‘D’’

last

{8} first
‘B’’ ‘C’’

y
‘D’’

menjadi :

Bab 5 Representasi Data halaman 81


last

{9} first
‘B’’ ‘C’’ ‘D’’

Gambar logiknya untuk kasus menambah elemen bila first menunjuk linear list yang
masih kosong : misalkan nilai x adalah karakter ‘D’‛.
Kondisi awal :
first last

{5 dan 6} y
‘D’’

Pointer baru y dibuat (4), kemudian elemen x di-assign ke data elemen y (5).
Link dari y tidak menunjuk kemanapun (6). Jika first sudah memiliki elemen (7)
pointer last elemen linknya digunakan untuk menunjuk elemen yang baru (8), pointer
last kemudian menunjuk elemen terakhir lagi sesuai fungsinya (9). Namun jika first
masih kosong, baik first maupun last menunjuk elemen baru (satu-satunya) yaitu y
(11). Fungsi mengembalikan linear list setelah disisipkan elemen di sebelah kanan
elemen terakhir (12).

1. template<class T>
2. void Chain<T>::Output(ostream& out) const
3. {// Insert the chain elements into the stream out.
4. ChainNode<T> *current;
5. for (current = first; current;
6. current = current->link)
7. out << current->data << " "; 8.
}

1. // overload <<
2. template <class T>
3. ostream& operator<<(ostream& out, const Chain<T>& x)
4. {x.Output(out); return out;}

Bab 5 Representasi Data halaman 82


// file citer.h

class ChainIterator
1. template<class T>
2. class ChainIterator {
3. public:
4. T* Initialize(const Chain<T>& c)
5. {location = c.first;
6. if (location) return &location->data;
7. return 0;}
8. T* Next()
9. {if (!location) return 0;
10. location = location->link;
11. if (location) return &location->data;
12. return 0;}
13. private:
14. ChainNode<T> *location;
15. };

// test chain iterator class

1. #include <iostream.h>
2. #include "chain.h"
3. #include "citer.h"
4.
5. void main(void)
6. {
7. Chain<int> L;
8. L.Insert(0,2);
9. L.Insert(1,6);
10. L.Insert(2,8);
11. L.Insert(1,4);
12. cout << "List is " << L << endl;
13. ChainIterator<int> p;
14. int *q = p.Initialize(L);
15. cout << "List in sequence is ";
16. while (q) {
17. cout << *q << ' ';
18. q = p.Next();
19. }

Bab 5 Representasi Data halaman 83


20. cout << endl;
21. }

List is 1 2 3 4 5 6

// output a chain using a chain iterator

1. #include <iostream.h>
2. #include "chain.h"
3. #include "citer.h"
4.
5. void main(void)
6. {
7. int *x;
8. Chain<int> X;
9. ChainIterator<int> c;
10. X.Insert(0,6);
11. X.Insert(0,5);
12. X.Insert(0,4);
13. X.Insert(0,3);
14. X.Insert(0,2);
15. X.Insert(0,1);
16. cout << "List is ";
17. x = c.Initialize(X);
18. while (x) {
19. cout << *x << ' ';
20. x = c.Next();
21. }
22. cout << endl;
23. }

CircularList
1. template<class T>
2. int CircularList<T>::Search(const T& x) const
3. {// Locate x in a circular list with head node.
4. ChainNode<T> *current = first->link;
5. int index = 1; // index of current
6. first->data = x; // put x in head node
7.
8. // search for x
9. while (current->data != x) {

Bab 5 Representasi Data halaman 84


10. current = current->link);
11. index++;
12. }
13. // are we at head?
14. return ((current == first) ? 0 : index);
15. }

1. template <class T> class Double;


2.
3. template <class T>
4. class DoubleNode {
5. friend Double<T>;
6. private:
7. T data;
8. DoubleNode<T> *left, *right;
9. };

// file double.h

1. #include <stdlib.h>
2. #include <iostream.h>
3. #include "dnode.h"
4. #include "xcept.h"
5.
6. template<class T>
7. class Double {
8. public:
9. Double() {LeftEnd = RightEnd = 0;};
10. ~Double();
11. int Length() const;
12. bool Find(int k, T& x) const;
13. int Search(const T& x) const;
14. Double<T>& Delete(int k, T& x);
15. Double<T>& Insert(int k, const T& x);
16. void Output(ostream& out) const;
17. private:
18. DoubleNode<T> *LeftEnd, *RightEnd;

Bab 5 Representasi Data halaman 85


19. };

Bab 5 Representasi Data halaman 86


SKENARIO PERKULIAHAN MINGGU 6

Persiapan [50 menit]

01. Mahasiswa mengerjakan Pretest Praktikum


02. Mahasiswa mempelajari kaedah konstruksi Link List menggunakan Struct
03. Mahasiswa membuat contoh konstruksi Link List menggunakan Struct beserta operasi
dasar Link List
04. Catatan :
a. Boleh belajar bersama kelompok masing-masing

b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]

00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing

01. Dosen membuka perkuliahan


02. Dosen memberikan contoh konstruksi Link List menggunakan Struct
03. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
04. Dosen menjelaskan pembuatan konstruksi Link List menggunakan Struct
05. Mahasiswa mengikuti dengan compilernya masing-masing
06. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]

01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya masing-


masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]

01. Dosen memberikan rangkuman materi kuliah minggu ini


02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 6 Link List halaman 87


Bab VI

Link list

Tujuan Pembelajaran:

1. Mahasiswa memahami struktur (komponen) link list


2. Mahasiswa dapat mendeklarasikan variabel link list
3. Mahasiswa dapat melakukan operasi dasar link list: menambah dan menghapus
elemen link list

Pra syarat:

1. Mahasiswa sudah memahami struct atau class


2. Mahasiswa dapat mengakses bagian dari komponen struct atau class
3. Mahasiswa memahami memori dinamis (pointer)

A. Pendahuluan

Link list adalah sebuah cara menyimpan data secara dinamis. Arti dinamis adalah banyak
nya data yang di simpan di dalam memori berubah ubah setiap kali progam di jalankan
(running). Bayangkan kita memiliki 5 buah data yang di simpan dalam array menggunakan
deklarasi berikut:

int a [5];

data akan di simpan di dalam array dengan penunjuk indeks misalnya a[2] = -3 artinya data -3
di simpan dalam array a dalam indeks 2

kita akan mulai mempelajari link list pada operasi menambah data. Perhatikan gambar
berikut:

Bab 6 Link List halaman 88


Class node memiliki 2 komponen yaitu berupa data bertipe int dan pointer ke (Node *)
berikut.

Kita deklarasikan variabel A bertipe pointer ke (Node *)

Node *A = new Node;

Untuk mengakses komponen data menggunakan variabel pointer kita menggunakan operator
panah ->. Jadi bila komponen data dari variabel A kita isi dengan angka 1 menggunakan
pernyataan

A->data = 1;

Untuk komponen berikut bila pointer tidak digunakan menunjuk kemana pun kita isi dengan
00 atau null. Gambar logika nya tampak seperti ini

Langkah yang sama kita gunakan untuk membuat Node B dengan pernyataan berikut

Gambar logic nya adalah

Bab 6 Link List halaman 89


Sekarang kita telah memiliki 2 variabel Node A dan B yang masing masing berisi angka 1
dan 2 berturut turut. Sekarang kita akan menghubungkan pointer berikut di A (tadi nya null)
untuk menunjuk objek yang di tunjuk oleh pointer B dengan pernyataan:

A->berikut = B;

Sehingga gambar logic nya akan terlihat seperti ini (perhatikan panah merah) yang mewakili
pernyataan di atas

Operasi ini bisa kita namakan menambah elemen di belakang (elemen 1 di ikuti dengan
elemen 2) dari variabel pointer A. Untuk menambah elemen berikut nya bisa di lakukan
dengan cara yang sama, dengan memperhatikan komponen berikut untuk menyambung data
yang baru

Di dalam array kita bisa membayangkan

data 1 2

indeks 0 1 2 3 4

Menampilkan isi link list

Tidak seperti array yang menampilkan isi data nya dengan cara menggunakan indeks,
untuk menampilkan isi array kita harus mulai dari depan (pointer pertama). Asumsikan kita
memiliki gambar logic berikut

Bab 6 Link List halaman 90


Kita buat pointer baru yang namanya jalan. Kita posisikan pointer jalan ini menunjuk objek
yang di tunjuk oleh pointer A

Pernyataan nya adalah Node *jalan = A;

Kita akan menjelajahi setiap elemen sampai (while) pointer jalan tidak menunjuk kemanapun
(yaitu null) artinya, kita akan menjalani bila pointer jalan tidak sama dengan 0. Perhatikan
gambar berikut

Saat

cout << “Isi elemen : “ << jalan ->data << endl;

Isi elemen : 1

Pernyataan:

jalan = jalan-> berikut;

mengubah penunjuk jalan dari objek data 1 ke objek berikutnya (yaitu objek data 2)

Gambar logic nya akan terlihat seperti ini

Bab 6 Link List halaman 91


Pointer jalan akan menunjuk null. Gambar logic nya akan terlihat seperti ini menandakan
bahwa pernyataan while berhenti

Menghapus elemen link list

Asumsikan pointer A memiliki 2 elemen seperti gambar berikut

Tujuan kita adalah menghapus elemen 1 (elemen 1 tidak bisa di akses oleh pointer A). Untuk
itu kita deklarasikan pointer hapus yang menunjuk objek yang di tunjuk oleh pointer A
(langkah 1) kemudian pointer A menunjuk elemen 2 (berikutnya langkah 2) sebagaimana
gambar berikut ini

Posisi langkah 1 dan 2 akan terlihat secara logic seperti gambar di bawah ini

Bab 6 Link List halaman 92


Langkah terakhir menggunakan pernyataan :

delete hapus;

gambar logic nya akan terlihat sebagai berikut

Dengan demikian pointer A hanya memiliki 1 elemen yaitu objek 2, objek yang berisi elemen
2

Bab 6 Link List halaman 93


Diskusi

1. Diskusikan untuk membuat gambar logika menyisipkan (menambah elemen di


tengah) sesuai posisi yang di kehendaki

2. Cobalah menyusun gambar logika beserta pernyataan C++ untuk menghapus elemen
di belakang nya

Latihan

1. Buatlah algoritma untuk menyalin seluruh elemen sebuah link list.


2. Buatlah algoritma untuk menyalin seluruh elemen sebuah link list yang genap.
3. Buatlah algoritma untuk menghapus seluruh elemen sebuah link list yang genap.

Bab 6 Link List halaman 94


SKENARIO PERKULIAHAN MINGGU 7

Persiapan [50 menit]

01. Mahasiswa mengerjakan Pretest Praktikum


02. Mahasiswa mempelajari materi Berbagai Macam Link List
03. Mahasiswa mencari perbedaan materi Berbagai Macam Link List
04. Mahasiswa membuat contoh materi Berbagai Macam Link List
05. Catatan :
a. Boleh belajar bersama kelompok masing-masing

b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]

00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing

01. Dosen membuka perkuliahan


02. Dosen memberikan contoh konstruksi node link list melingkar
03. Dosen memberikan perbedaan link list biasa dan link list melingkar dengan
menginisialisasi link list masing masing
04. Dosen memberikan perbedaan operasi menambah dan menghapus di depan dari kedua
jenis link list
05. Dosen memberikan perbedaan operasi menambah dan menghapus di belakang dari
kedua jenis link list
06. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
07. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]

01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya masing-


masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain
05.
Penutup [20 menit]

01. Dosen memberikan rangkuman materi kuliah minggu ini


02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 7 Pengembangan Link List halaman 95


Bab VII

Pengembangan Link list

Tujuan pembelajaran

1. Mahasiswa mampu mengembangkan model link list yang lebih kompleks


2. Mahasiswa mampu mempraktekkan operasi operasi link list yang lebih kompleks

Pra Syarat

1. Mahasiswa menguasai operasi dasar link list (menambah dan menghapus elemen
dengan berbagai variasinya)

A. Circular link list

Circular link list di definisikan sebagai link list yang komponen elemen terakhirnya (pointer)
bukan null (link list biasa) namun menunjuk elemen pertama

Masih ingat dengan definisi class node berikut ?

Bila kita mendeklarasikan variabel pointer :

Node *A;

Untuk komponen link list nya komponen pointer berikut diberi nlai awal null (untuk link list
biasa). Untuk circular link list, komponen pointer berikut ini menunjuk ke objek yang di
tunjuk pointer A dengan pernyataan berikut:

A->berikut = A;

Apa motivasi kita membuat circular link list ?

Bab 7 Pengembangan Link List halaman 96


Saat kita membuat link list biasa, pointer dari posisi awal hanya akan maju, tak bisa lagi
melihat elemen sebelumnya. Dengan circular link list sifat maju masih di pertahankan namun
pada suatu ketika saat pointer berikut sudah berada pada elemen terakhir bisa melihat elemen
pertama. Dengan demikian akan bisa melihat elemen elemen selanjutnya.

Diskusi

1. Diskusi kan untuk membuat gambar logic operasi menambah elemen di depan, di
tengah (dimana kita menghendaki), dan di belakang untuk circular link list
2. Diskusi kan untuk membuat gambar logic operasi menghapus elemen di depan, di
tengah (dimana kita menghendaki), dan di belakang untuk circular link list

B. Doubly link list

Tentu akan menyenangkan bila kita lebih leluasa untuk melihat elemen depan atau
elemen belakang tidak dengan menunggu setelah elemen terakhir (seperti karakter dari
circular link list). Maka kita akan mengembangkan pointer mundur sebagai sebuah fitur baru
selain pointer maju. Karena ada 2 pointer untuk melihat elemen yang di depan atau
sebelumnya maka di namakan doubly link list. Class node sebelumnya kita tambahkan 1
pointer dengan nama sebelum untuk operasi mundur. Dengan demikian class node akan
menjadi

class Node {
public:

Int data;
Node *berikut;
Node *sebelum;
};
Saat mendeklarasikan variabel A bertipe Node:

Node *A = new Node;

Kita memberikan nilai null pada kedua komponen pointer:

Bab 7 Pengembangan Link List halaman 97


A-> berikut = 0;

A-> sebelum = 0;

Untuk mengisi data elemen pertama menggunakan pernyataan:

A-> data = 1;

Dengan demikian kita telah memiliki doubly link list A yang memiliki 1 elemen.

Menambah elemen di depan

Dengan cara yang sama kita akan membuat Node baru dengan variabel B yang di isi data 2
sebagai berikut:

Node *B = new Node;

B-> data = 2;

B-> berikut = 0;

B-> sebelum = 0;

Node B dengan data 2 ini akan kita letakan pada posisi di depan Node dengan data 1 dengan
langkah langkah berikut ini

Pointer berikut dari B menunjuk objek yang di tunjuk oleh pointer A:

B-> berikut = A;

Pointer sebelum dari variabel A menunjuk ke objek yang di tunjuk pointer B

A-> sebelum = B;

Sekarang pointer A menunjuk ke objek yang di tunjuk pointer B

A=B

Sekarang pointer A memiliki 2 elemen yaitu Node berisi 2 dan Node yang berisi 1

Untuk menambah data di depan di lakukan berulang ulang dengan cara yang serupa

Bab 7 Pengembangan Link List halaman 98


Diskusi

1. Diskusi kan untuk membuat gambar logic operasi menambah elemen di depan, di
tengah (dimana kita menghendaki), dan di belakang untuk doubly link list
2. Diskusi kan untuk membuat gambar logic operasi menghapus elemen di depan, di
tengah (dimana kita menghendaki), dan di belakang untuk doubly link list

Bab 7 Pengembangan Link List halaman 99


SKENARIO PERKULIAHAN MINGGU 8

Persiapan [50 menit]


01. Mahasiswa mengerjakan Pretest Praktikum
02. Mahasiswa mempelajari Stact dan Operasi Dasarnya
03. Mahasiswa membuat contoh Stact dan Operasi Dasarnya
04. Catatan :
a. Boleh belajar bersama kelompok masing-masing
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]


00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing
01. Dosen membuka perkuliahan
02. Dosen meminta mahasiswa menentukan Tugas Proyek tiap kelompok
03. Dosen menjelaskan mekanisme Tugas Proyek
04. Dosen memberikan contoh Stact dan Operasi Dasarnya
05. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
06. Dosen menjelaskan pembuatan Stact dan Operasi Dasarnya
07. Mahasiswa mengikuti dengan compilernya masing-masing
08. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]


01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya
masing-masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]


01. Dosen memberikan rangkuman materi kuliah minggu ini
02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen meminta setiap kelompok mengumpulkan topik Tugas Proyek
05. Dosen menutup perkuliahan

Bab 8 Stack (Tumpukan) halaman 100


Bab VIII

Stack (Tumpukan)
Tujuan Pembelajaran

1. mahasiswa memahami konsep stack (tumpukan)

2. mahasiswa dapat menerapkan konsep stack dalam bahasa pemrograman C++

A. Pendahuluan

Stack adalah struktur yang sifatnya LIFO (Last In First Out), yaitu yang masuk
belakangan akan keluar duluan. Dalam kehidupan sehari-hari dapat kita jumpai
contoh stack seperti : tumpukan buku, buku telepon, tumpukan koin (uang logam).
B. Implementasi dengan array

Struktur data :

Ada dua operasi yang digunakan pada stack, yaitu push (memasukkan elemen
ke stack) dan pop (mengeluarkan elemen dari stack).

Program 5.1. ADT Kelas Stack


1. template<class T>
2. class Stack {
3. public:
4. Stack(int MaxStackSize = 10);
5. ~Stack() {delete [] stack;}
6. int IsEmpty() const {return top == -1;}
7. int IsFull() const {return top == MaxTop;}
8. T Top() const;
9. Stack<T>& Add(const T& x);
10. Stack<T>& Delete(T& x);
11. private:
12. int top;
13. int MaxTop;
14. T *stack;
15. };

Bab 8 Stack (Tumpukan) halaman 101


Konstruktor kelas Stack mengawali array dengan maksimum elemen
MaxStackSize sebanyak 10. Gambar logiknya adalah sebagai berikut : (bayangkan
stacknya rubuh)
operasi selalu diterapkan
-4 2 5 … -7 
pada puncak stack
1 2 3 … 10  atas

Method IsEmpty digunakan untuk menguji apakah stack kosong atau tidak.
Stack kosong didefinisikan sebagai top (data member yang menunjukkan posisi
teratas stack sama dengan –1). Method IsFull digunakan untuk menguji apakah stack
dalam keadaan penuh atau tidak. Stack dalam keadaan penuh didefinisikan apabila
top sama dengan MaxTop, yaitu member data yang menunjukkan harga tertinggi
untuk posisi puncak stack. Data member stack sendiri merupakan pointer yang
menunjuk ke array yang digunakan untuk merepresentasikan stack.
Method Top digunakan untuk menampilkan elemen teratas dari stack. Method
Add untuk menambah elemen x ke stack, dan method Delete untuk menhapus
elemen teratas dari stack dan mewujudkannya elemen yang dihapus pada x.

Program 5.2. Konstruktor kelas Stack


1. template<class T>
2. Stack<T>::Stack(int MaxStackSize)
3. {
4. MaxTop = MaxStackSize - 1;
5. stack = new T[MaxStackSize];
6. top = -1;
7. }

Konstruktor Stack membatasi MaxTop sebanyak MaxStackSize – 1.


Pemesanan memori sebanyak MaxStackSize, dan top diset sama dengan –1 (stack
masih kosong).

Program 5.3. Mengembalikan elemen teratas stack


1. template<class T>

Bab 8 Stack (Tumpukan) halaman 102


2. T Stack<T>::Top() const
3. {
4. if (IsEmpty()) throw OutOfBounds();
5. else return stack[top];
6. }

Asal stack tidak kosong, method Top akan mengembalikan mengembalikan


elemen teratas dari stack.
Program 5.4. Menambah elemen x ke stack
1. template<class T>
2. Stack<T>& Stack<T>::Add(const T& x)
3. {
4. if (IsFull()) throw NoMem();
5. stack[++top] = x;
6. return *this;
7. }

Penambahan elemen dapat dilakukan bila stack tidak dalam kondisi penuh.
Caranya, elemen x (yang dimasukkan lewat parameter) akan diletakkan pada posisi
top + 1 (di atas posisi puncak saat ini).
Program 5.5. Menghapus elemen stack (teratas)
dan menempatkan elemen yang di-pop ke x
1. Template<class T>
2. Stack<T>& Stack<T>::Delete(T& x)
3. {
4. if (IsEmpty()) throw OutOfBounds();
5. x = stack[top--];
6. return *this;
7. }

Penghapusan dilakukan dengan cara sebagai berikut. Elemen yang akan


dihapus di-assign ke x, lalu indeks array turun satu (top--) (5). Namun apabila stack
kosong, tentu saja tidak ada elemen yang akan di-pop, komentar kesalahan akan
diberikan (4).

Program 5.6. Kelas LinkedStack turunan dari kelas Chain<T>


1. template<class T>

Bab 8 Stack (Tumpukan) halaman 103


2. class LinkedStack : private Chain<T> {
3. public:
4. bool IsEmpty() const
5. {return Chain<T>::IsEmpty();}
6. bool IsFull() const;
7. T Top() const
8. {if (IsEmpty()) throw OutOfBounds();
9. T x;
10. Find(1, x);
11. return x;}
12. LinkedStack<T>& Add(const T& x)
13. {Insert(0, x); return *this;}
14. LinkedStack<T>& Delete(T& x)
15. {Chain<T>::Delete(1, x); return *this;}
16. };

Kelas LinkedStack diturunkan secara private dari kelas Chain (2). Hal ini
dimaksudkan bahwa kelas LinkedStack tidak diinginkan untuk diturunkan lagi. Data
member diambil dari kelas Chain yaitu pointer first yang menunjuk elemen pertama
(teratas).
Method IsEmpty digunakan untuk mengecek apakah stack kosong atau tidak.
Hal ini dilakukan dengan cara mengambil method IsEmpty dari kelas Chain (5).
Method IsFull digunakan untuk mengecek stack apakah dalam keadaan penuh atau
tidak. Method Top berfungsi untuk mengembalikan elemen teratas, hal ini dilakukan
dengan cara dicari elemen pertama dari stack (10) jika ditemukan (artinya stack tidak
kosong) misalkan x, kemudian x dikembalikan (11). Jika ternyata stack kosong,
komentar kesalahan akan dikembalikan (8).
Method Add berfungsi untuk menyisipkan elemen x pada stack (12).
Penyisipan elemen baru akan diletakkan pada elemen pertama link list (dan selalu
ditambah di depan) dengan memanfaatkan method Insert x pada posisi 0 (13).
Dalam istilah stack penyisipan ini dinamakan operasi push.
Method Delete berfungsi untuk menghapus (operasi pop) (14). Hal ini
dilakukan dengan cara menghapus elemen pertama (terdepan) dari stack (15).
Elemen yang dihapus di-assign (dihasilkan) pada x.

Bab 8 Stack (Tumpukan) halaman 104


Program 5.7. Mengecek apakah stack penuh atau tidak
1. template<class T>
2. bool LinkedStack<T>::IsFull() const
3. {
4. try {ChainNode<T> *p = new ChainNode<T>;
5. delete p; return false;}
6. catch (NoMem) {return true;}
7. }

Method IsFull digunakan untuk mengecek stack apakah dalam keadaan penuh
atau tidak. Caranya, memori dipesan (4) kemudian dihapus lagi (5). Apabila sukses
dilakukan berarti stack tidak penuh, false dikembalikan. Namun bila tidak terdapat
memori (6), true dikembalikan.

Program 5.8. Kelas Node


1. template <class T> class LinkedStack;
2. template <class T> class LinkedQueue;
3.
4. template <class T>
5. class Node {
6. friend LinkedStack<T>;
7. friend LinkedQueue<T>;
8. private:
9. T data;
10. Node<T> *link;
11. };

Kelas Node mempunyai dua data member yaitu data digunakan untuk
menyimpan informasi (9), dan pointer link yang digunakan untuk menunjuk elemen
berikutnya.

Program 5.9. File node.h


1. template<class T>
2. class LinkedStack {
3. public:
4. LinkedStack() {top = 0;}

Bab 8 Stack (Tumpukan) halaman 105


5. ~LinkedStack();
6. int IsEmpty() const {return top == 0;}
7. int IsFull() const;
8. T Top() const;
9. LinkedStack<T>& Add(const T& x);
10. LinkedStack<T>& Delete(T& x);
11. private:
12. Node<T> *top;
13. };

Kelas LinkedStack di atas mempunyai data member pointer top untuk


menunjuk elemen teratas (terdepan) (12).

Program 5.10. Stack destructor.


1. template<class T>
2. LinkedStack<T>::~LinkedStack()
3. {
4. Node<T> *next;
5. while (top) {
6. next = top->link;
7. delete top;
8. top = next;
9. }
10. }

Destruktor stack digunakan untuk membebaskan semua memori yang


digunakan oleh stack. Hal ini dilakukan dengan cara menghapus elemen demi elemen
(7) dari stack diawali dari puncak stack (5) asal puncak stack tidak kosong. Elemen
berikutnya yang akan dihapus ditunjuk oleh (6). Pola penghapusan ini tidak lain
merupakan implementasi penghapusan node link list pada elemen terdepan.

Program 5.11. Menambahkan elemen x pada akhir queue.


1. template<class T>
2. int LinkedStack<T>::IsFull() const
3. {
4. try {Node<T> *p = new Node<T>;
5. delete p;

Bab 8 Stack (Tumpukan) halaman 106


6. return 0;} //false;}
7. catch (NoMem) {return 1;} }
8. }

Pengecekan apakah stack penuh (7) atau tidak menggunakan exception


handling. Bila tidak ada memori lagi yang dialokasikan, dikatakan stack penuh.

Program 5.12. Mengembalikan elemen puncak stack


1. template<class T>
2. T LinkedStack<T>::Top() const
3. {
4. if (IsEmpty()) throw OutOfBounds();
5. return top->data;
6. }

Bila diinginkan kita bisa mengetahui elemen apakah di puncak stack (5)
dengan menggunakan method Top(). Tentu saja apabila stack tersebut tidak kosong
(4).
Program 5.13. Menambahkan elemen x pada puncak stack.
1. template<class T>
2. LinkedStack<T>& LinkedStack<T>::Add(const & x)
3. {
4. Node<T> *p = new Node<T>;
5. p->data = x;
6. p->link = top;
7. top = p;
8. return *this;
9. }

Node baru dideklarasikan p (4). Penambahan elemen pada stack menggunakan


cara menambah elemen di depan. Elemen x di-assign (dimasukkan) ke data (5),
sedangkan link menunjuk ke elemen pertama (top) (6). Kemudian top menunjuk ke
p (7).
Program 5.14. Menghapus elemen puncak stack.
1. template<class T>
2. LinkedStack<T>& LinkedStack<T>::Delete(T& x)
3. {

Bab 8 Stack (Tumpukan) halaman 107


4. if (IsEmpty()) throw OutOfBounds();
5. x = top->data;
6. Node<T> *p = top;
7. top = top->link;
8. delete p;
9. return *this;
10. }

Menghapus elemen stack dilakukan dengan cara menghapus elemen terdepan


dari link list. Pertama kali pointer p menunjuk elemen puncak stack (6). Kemudian
pointer top bergeser ke elemen berikutnya (7). Memori dibebaskan (8), sementara
bila pemanggil ingin mengetahui elemen apa yang dihapus, data di-assign ke x (5).

C. Aplikasi stack : pengecekan tanda kurung

Program 5.15. Pengecekan tanda kurung

1. #include <iostream.h>
2. #include <string.h>
3. #include <stdio.h>
4. #include "stack.h"
5.
6. const int MaxLength = 100;
7. void PrintMatchedPairs(char *expr)
8. {
9. Stack<int> s(MaxLength);
10. int j, length = strlen(expr);
11.
12. for (int i = 1; i <= length; i++) {
13. if (expr[i - 1] == '(') s.Add(i);
14. else if (expr[i - 1] == ')')
15. try {s.Delete(j); // unstack match
16. cout << j << ' ' << i << endl;}
17. catch (OutOfBounds)
18. {cout << "No match for right parenthesis" << " at " << i << endl;}
19. }
20.
21. while (!s.IsEmpty()) {
22. s.Delete(j);
23. cout << "No match for left parenthesis at " << j << endl;}

Bab 8 Stack (Tumpukan) halaman 108


24. }
25.
26. void main(void)
27. {
28. char expr[MaxLength];
29. cout << "Type an expression of length at most " << MaxLength << endl;
30. cin.getline(expr, MaxLength);
31. cout <<"The pairs of matching parentheses in" << endl;
32. puts(expr);
33. cout <<"are" << endl;
34. PrintMatchedPairs(expr);
35. }
36.

Maksimum panjang ekspresi dibatasi 100 (6). Kita gunakan array s untuk
menampung ekspresi (9). Ekspresi dapat dipandang sebagai string, sehingga kita
dapat memperoleh panjangnya (10).
Baris 12 sampai 19 digunakan untuk melacak tanda kurung ( dan ). Jika
ketemu kurang buka ‘(‘ (13) masukkan letak elemen setelah tanda kurung ke stack s,
dan jika ketemu tanda kurung tutup’‛)’‛ (14) hapus elemen dari stack s (15). Sebagai
contoh diberikan string ekspresi :
(a-b+(-b)

Indeks string dimulai dari 0. Dengan demikian kurung buka pertama berada
pada posisi 0, posisi 1 (angka 1) masuk stack s. Pelacakan berlanjut, ‘(‘ kedua
ditemukan pada posisi 5, 6 masuk stack s. Berikutnya ditemukan ‘)’‛ pada posisi 8.
Dengan demikian j = 6 dihapus dari stack s, dicetak 6 kemudian posisi i = 9 juga
dicetak. Jadi pasangan kurung ditemukan pada posisi 6 dan 9. Pelacakan dilanjutkan,
namun sampai akhir ekspresi tidak ditemukan pasangan ‘)’‛ (21 sampai 23).
Sehingga akan dihapus sisa elemen yang ada di stack (22), dicetak posisi-posisinya,
yaitu 1.
D. Aplikasi stack : Menara Hanoi

Program menara Hanoi berikut ini, memanfaatkan stack memori (dengan cara
pemanggilan rekursif) untuk merepresentasikan posisi piringan dalam tonggak

Bab 8 Stack (Tumpukan) halaman 109


(menara). Terdapat 4 parameter, yaitu n yang menyatakan banyaknya piringan, dan
parameter x, y dan z untuk mewakili tonggak pertama, ketiga, dan kedua.
Program 5.16. Overload operator penugasan.
1. #include <iostream.h>
2.
3. void TowersOfHanoi(int n, int x, int y, int z)
4. {// Move the top n disks from tower x to tower y.
5. // Use tower z for intermediate storage.
6. if (n > 0) {
7. TowersOfHanoi(n-1, x, z, y);
8. cout << "Move top disk from tower "
9. << x << " to top of tower " << y << endl;
10. TowersOfHanoi(n-1, z, y, x);}
11. }
12.
13. void main(void)
14. {
15. cout << "Moves for a three disk problem are" << endl;
16. TowersOfHanoi(3,1,2,3);
}

Prinsip dari permainan menara Hanoi adalah memindahkan piringan paling


atas sebanyak n piringan dari x (menara pertama) ke y (menara ketiga) melalui z
(menara kedua), dengan syarat piringan yang besar tidak boleh berada di atas
piringan y kecil. Coba praktekkan hasil dari output di bawah ini.
Output :

Moves for a three disk problem are


Move top disk from tower 1 to top of tower 2
Move top disk from tower 1 to top of tower 3
Move top disk from tower 2 to top of tower 3
Move top disk from tower 1 to top of tower 2
Move top disk from tower 3 to top of tower 1
Move top disk from tower 3 to top of tower 2
Move top disk from tower 1 to top of tower 2

Dari perilaku menara Hanoi di atas, kita buat kelas Hanoi dengan
memanfaatkan kelas Stack (berada pada file stack.h) berikut.

Bab 8 Stack (Tumpukan) halaman 110


Program 5.17. Aplikasi kelas Stack : Manara Hanoi
1. #include <iostream.h>
2. #include "stack.h"
3. class Hanoi {
4. friend void TowersOfHanoi(int);
5. public:
6. void TowersOfHanoi(int n, int x, int y, int z);
7. private:
8. Stack<int> *S[4]; // pointer array untuk stack
9. };
10.
11. void Hanoi::TowersOfHanoi(int n, int x, int y, int z)
12. {
13. int d; // banyaknya piringan
14. if (n > 0) {
15. TowersOfHanoi(n-1, x, z, y);
16. S[x]->Delete(d); // menghapus piringan dari x
17. S[y]->Add(d); // meletakkan piringan ke y
18. cout << "Move disk " << d << " from tower "
19. << x << " to tower " << y << endl;
20. TowersOfHanoi(n-1, z, y, x);}
21. }
22.
23. void TowersOfHanoi(int n)
24. { Hanoi X;
25. // membuat tiga tumpukan berukuran n
26. X.S[1] = new Stack<int> (n);
27. X.S[2] = new Stack<int> (n);
28. X.S[3] = new Stack<int> (n);
29.
30. for (int d = n; d > 0; d--)
31. X.S[1]->Add(d); // menambah d ke menara 1
32. X.TowersOfHanoi(n, 1, 2, 3);
33. }
34.
35. void main(void)
36. {
37. cout << "Moves for a three disk problem are" << endl;
38. TowersOfHanoi(3);
39. }

Bab 8 Stack (Tumpukan) halaman 111


Latihan
Pelajarilah bagaimana implementasi kelas Stack program 5.17 di atas.
Amatilah perbedaan dan persamaan dengan program menara Hanoi menggunakan
fungsi rekursi.

Bab 8 Stack (Tumpukan) halaman 112


SKENARIO PERKULIAHAN MINGGU 9

Persiapan [50 menit]


01. Mahasiswa mengerjakan Pretest Praktikum
02. Mahasiswa mempelajari Antrian dan Operasi Dasarnya
03. Mahasiswa membuat contoh Antrian dan Operasi Dasarnya
04. Catatan :
a. Boleh belajar bersama kelompok masing-masing
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]


00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing
00. Mahasiswa mengumpulkan topik Tugas Proyek
01. Dosen membuka perkuliahan
02. Dosen memberikan contoh Antrian dan Operasi Dasarnya
03. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
04. Dosen menjelaskan pembuatan Antrian dan Operasi Dasarnya
05. Mahasiswa mengikuti dengan compilernya masing-masing
06. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]


01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya
masing-masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]


01. Dosen memberikan rangkuman materi kuliah minggu ini
02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 9 Antrian halaman 113


Bab IX

Antrian
Tujuan Pembelajaran
1. Mahasiswa memahami konsep antrian

2. Mahasiswa dapat menerapkan konsep antrian dalam bahasa pemrograman C++

A. Pendahuluan

Antrian (Queue) merupakan kumpulan data di mana penambahan data dilakukan di


“belakang” (rear), dan penghapusan dilakukan pada elemen yang berada di “depan”
(front). Prinsip dasar antrian adalah yang datang dulu dilayani dulu (First Come First
Serve [FCFS] atau First In First Out [FIFO]).
Contoh :

 Pembayaran rekening telepon

 Fasilitas print spool (antrian mencetak) pada jaringan komputer

 Bila ada “kebijakan” lain, misal adanya prioritas tertentu priority queue.

Misalkan disajikan antrian dengan 5 elemen. Ilustrasi kejadian-kejadian dapat


digambarkan sebagai berikut :
1. Inisialisasi antrian (antrian dalam keadaan kosong)

depan

“pintu” keluar “pintu” masuk

belakang

2. menambah elemen (enqueue) A, B, dan C berturut-turut

Bab 9 Antrian halaman 114


depan

“pintu” keluar A B C “pintu” masuk

belakang
Jadi pointer depan digunakan untuk menunjuk ke elemen terdepan dan pointer
belakang digunakan untuk menunjuk ke elemen paling belakang. Setiap kali operasi
enqueue dilakukan, pointer belakang akan bergeser ke belakang satu langkah.
3. menghapus elemen (dequeue)
dequeue
depan

“pintu” keluar B C “pintu” masuk

belakang

B. Antrian dengan menggunakan array


Antrian dapat diimplementasikan dengan menggunakan array maupun linear list.
Tipe data abstrak dari queue dengan menggunakan array adalah sebagai berikut
ADT queue {

instan

elemen linear list terurut, yang terdepan dinamakan depan (front), yang

terakhir dinamakan ekor (rear).

operasi

create() : membuat queue kosong

IsEmpty() : mengembalikan true jika queue kosong, false jika tidak

Bab 9 Antrian halaman 115


kosong

IsFull() : mengembalikan true jika queue penuh, false jika tidak penuh

First() : mengembalikan elemen pertama dari queue

Last() : mengembalikan elemen terakhir dari queue

Add(x) : menambah elemen x pada queue dinamakan operasi enqueue

Delete(x) : menghapus elemen terdepan dari queue dinamakan operasi

dequeue, dan meletakkan elemen ini ke x.

Implementasi kelas queue disajikan dalam tabel berikut ini.

Program 6.1. Kelas Queue


1. template<class T>
2. class Queue {
3. public:
4. Queue(int MaxQueueSize = 10);
5. ~Queue() {delete [] queue;}
6. bool IsEmpty() const {return front == rear;}
7. bool IsFull() const {
8. return ( ((rear + 1) % MaxSize == front) ? 1 : 0);}
9. T First() const;
10. T Last() const;
11. Queue<T>& Add(const T& x);
12. Queue<T>& Delete(T& x);
13. private:
14. int front;
15. int rear;
16. int MaxSize;
17. T *queue;
18. };

Bab 9 Antrian halaman 116


Kelas Queue mempunyai data member sebanyak 4, yaitu front (untuk menyimpan
elemen pertama) (14), rear (untuk menyimpan elemen terakhir) (15), MaxSize (untuk
menyimpan maksimum elemen queue) (16), dan queue.
Konstruktor Queue menggunakan maksimum elemen sebanyak 10 (4). Method
IsEmpty digunakan untuk menguji apakah queue kosong atau tidak. Queue dikatakan
kosong jika front = rear (6). Method IsFull digunakan untuk menguji apakah queue
dalam keadaan penuh atau tidak. Queue dikatakan penuh jika (rear + 1) % MaxSize =
front (7 dan 8). Method First digunakan untuk menampilkan elemen pertama (9)
sedangkan untuk menampilkan elemen terakhir digunakan method Last (10). Method
Add digunakan untuk menambah elemen x ke dalam queue (11), sedangkan method
Delete digunakan untuk menghapus elemen x dari queue (12).

Program 6.2. Konstruktor kelas Queue, membuat queue


kosong yang berkapasitas sebanyak MaxQueueSize.
1. template<class T>
2. Queue<T>::Queue(int MaxQueueSize)
3. {
4. MaxSize = MaxQueueSize + 1;
5. queue = new T[MaxSize];
6. front = rear = 0;
7. }

Parameter MaxQueueSize langsung di-assign ke data member MaxSize


(ditambah 1 (4)). Queue direpresentasikan bertipe T (bisa int, float, double dan
sebagainya) sebanyak MaxSize. front dan rear di-set sama dengan 0, artinya queue
kondisinya masih kosong (6).

Program 6.3. Mengembalikan elemen pertama queue.


1. template<class T>

Bab 9 Antrian halaman 117


2. T Queue<T>::First() const
3. {
4. return queue[(front + 1) % MaxSize];
5. }

Program 6.4. Mengembalikan elemen terakhir queue.


1. template<class T>
2. T Queue<T>::Last() const
3. {
4. return queue[rear];
5. }

Untuk melihat elemen terakhir dari antrian cukup mengakses elemen pada posisi
rear (belakang) (4) dari array queue.

Program 6.5. Menambahkan elemen x pada akhir queue.


1. template<class T>
2. Queue<T>& Queue<T>::Add(const T& x)
3. {
4. rear = (rear + 1) % MaxSize;
5. queue[rear] = x;
6. return *this;
7. }

Program 6.6. Menghapus elemen pertama


dan menyimpannya pada x.
1. template<class T>
2. Queue<T>& Queue<T>::Delete(T& x)
3. {
4. front = (front + 1) % MaxSize;
5. x = queue[front];
6. return *this;
7. }
Fungsi main yang digunakan untuk mensimulasikan queue adalah sebagai berikut
:

Bab 9 Antrian halaman 118


Program 6.7. Main function kelas Queue
1. #include <iostream.h>
2. #include "queue.h"
3.
4. void main(void)
5. {
6. Queue<int> Q(3);
7. int x;
8. try {Q.Add(1).Add(2).Add(3).Add(4);
9. cout << "No queue add failed" << endl;}
10. catch (NoMem)
11. {cout << "A queue add failed" << endl;}
12. cout << "Queue is now 123" << endl;
13. Q.Delete(x);
14. cout << "Deleted " << x << endl;
15. cout << Q.First() << " is at front" << endl;
16. cout << Q.Last() << " is at end" << endl;
17. try {
18. Q.Delete(x);
19. cout << "Deleted " << x << endl;
20. Q.Delete(x);
21. cout << "Deleted " << x << endl;
22. Q.Delete(x);
23. cout << "Deleted " << x << endl;
24. cout << "No queue delete failed " << endl;
25. }
26. catch (OutOfBounds)
27. {cout << "A delete has failed" << endl;}
28. }

Bab 9 Antrian halaman 119


Output :

A queue add failed


Queue is now 123
Deleted 1
2 is at front
3 is at end
Deleted 2
Deleted 3
A delete has failed

Queue Q dideklarasikan dengan maksimum elemen queue sebanyak 3 (6).


Dengan demikian ukuran maksimum memori yang dipesan sebanyak 4, sesuai dengan
konstruktor queue. Semua elemen queue bertipe int.
Ditambahkan elemen baru berturut-turut elemen 1, 2, 3 dan yang terakhir 4 (8).
Namun karena maksimum elemen queue sebanyak 3, maka elemen terakhir, yaitu 4 gagal
masuk queue (10). Jadi kita hanya mempunyai 3 elemen dalam queue Q dan (11)
dilaksanakan.
Kemudian dilakukan penghapusan elemen (13) dan harga x akan di-assign 1 yang
dicetak (14). Terlihat elemen terdepan sekarang adalah 2 (15) dan elemen terakhir
adalah 3 (16). Selanjutnya dilakukan penghapusan elemen sebanyak 3 kali (18 - 23).
Namun karena saat penghapusan yang terakhir queue sudah kosong maka (27)
dilaksanakan. Cobalah dengan kasus hanya 3 elemen yang dimasukkan dan hanya 3 kali
penghapusan dilakukan. Lihatlah perbedaan outputnya.

Bab 9 Antrian halaman 120


C. Antrian dengan menggunakan link list

Program 6.8. Kelas Node


1. template <class T> class LinkedStack;
2. template <class T> class LinkedQueue;
3.
4. template <class T>
5. class Node {
6. friend LinkedStack<T>;
7. friend LinkedQueue<T>;
8. private:
9. T data;
10. Node<T> *link;
11. };

Kelas Node mempunyai dua data member yaitu data untuk menyimpan data
bertipe T dan link suatu pointer yang digunakan untuk menunjuk ke suatu node.

Program 6.9. Kelas LinkedQueue


1. Template<class T>
2. class LinkedQueue {// FIFO objects
3. public:
4. LinkedQueue() {front = rear = 0;}
5. ~LinkedQueue();
6. bool IsEmpty() const
7. {return ((front) ? false : true);}
8. bool IsFull() const;
9. T First() const;
10. T Last() const;
11. LinkedQueue<T>& Add(const T& x);
12. LinkedQueue<T>& Delete(T& x);
13. private:
14. Node<T> *front; // pointer to first node
15. Node<T> *rear; // pointer to last node
16. };

Bab 9 Antrian halaman 121


Kelas LinkedQueue mempunyai dua data member yaitu pointer front (14) yang
menunjuk awal antrian, dan pointer rear yang menunjuk elemen akhir antrian (15).
Konstruktor LinkedQueue mengawali nilai front dan read tidak menunjuk
kemanapun (4). Method IsEmpty menguji apakah front menunjuk ke suatu elemen atau
tidak. Jika menunjuk ke suatu elemen false dikembalikan, artinya antrian tidak kosong,
dan jika tidak menunjuk kemanapun berarti antrian kosong (7). Method IsFull digunakan
untuk menguji apakah antrian penuh atau tidak (8).
Method First mengembalikan elemen pertama (terdepan) dari antrian (9),
sedangkan method Last mengembalikan elemen terakhir (paling belakang) dari antrian
(10).
Method Add (11) menambah elemen x pada antrian, sedangkan method Delete
digunakan untuk menghapus elemen dan menaruhnya pada x (12).

Program 6.10. Destruktor queue. Menghapus semua node.


1. template<class T>
2. LinkedQueue<T>::~LinkedQueue()
3. {
4. Node<T> *next;
5. while (front) {
6. next = front->link;
7. delete front;
8. front = next;
9. }
10. }

Destruktor kelas LinkedQueue menghapus elemen (7) demi elemen (5) dari depan
(5 dan 8).

Program 6.11. Apakah antrian penuh atau tidak

Bab 9 Antrian halaman 122


1. template<class T>
2. int LinkedQueue<T>::IsFull() const
3. {
4. Node<T> *p;
5. try {p = new Node<T>;
6. delete p;
7. return 0;} //false;}
8. catch (NoMem) {return 1;}
9. }

Method IsFull digunakan untuk mengecek apakah queue penuh atau tidak dengan
cara mencoba menambah elemen (5) dan kemudian menghapusnya (6). Apabila bisa
dilakukan berarti queue belum penuh (7). Namun apabila tidak ada memori yang
dialokasikan (8) yang berarti queue dalam keadaan penuh, true dikembalikan.
Program 6.12. Mengembalikan elemen pertama antrian
1. template<class T>
2. T LinkedQueue<T>::First() const
3. {
4. if (IsEmpty()) throw OutOfBounds();
5. return front->data;
6. }

Method First di atas digunakan untuk mengembalikan elemen pertama antrian


(5). Jika antrian kosong akan diberikan komentar kesalahan (4).
Program 6.13. Mengembalikan elemen terakhir dari antrian
1. template<class T>
2. T LinkedQueue<T>::Last() const
3. {
4. if (IsEmpty()) throw OutOfBounds();
5. return rear->data;
6. }

Program 6.14. Menambahkan elemen x pada akhir antrian.

Bab 9 Antrian halaman 123


1. template<class T>
2. LinkedQueue<T>& LinkedQueue<T>::Add(const T& x)
3. { // membuat node elemen baru
4. Node<T> *p = new Node<T>;
5. p->data = x;
6. p->link = 0;
7.
8. // menambah node baru queue paling belakang
9. if (front) rear->link = p; // queue not empty
10. else front = p; // queue empty
11. rear = p;
12.
13. return *this;
14. }

Parameter x digunakan untuk memasukkan elemen baru yang akan dimasukkan


ke queue (2). Baris 4 sampai 6 digunakan untuk membuat node baru. Pointer p (4)
digunakan untuk menunjuk node yang berisi x (di-assign pada data member data (5)),
sedangkan data member link tidak menunjuk ke manapun (6).
Baris 8 sampai 10 digunakan untuk menambah elemen di belakang. Jika baru
pertama kali (front = 0), pointer front langsung menunjuk node baru tersebut (9), pointer
rear juga langsung menunjuk node p (10). Jadi, pointer front maupun rear menunjuk p
(karena cuma satu-satunya elemen). Namun jika queue sudah ada elemennya, maka link
dari elemen terakhir digunakan untuk menggandeng node baru
(p) (8), lalu rear menunjuk p (10).

Pointer yang menunjuk queue yang telah ditambah elemen baru dikembalikan

(12).

Program 6.15. Menghapus elemen pertama antrian


1. template<class T>

Bab 9 Antrian halaman 124


2. LinkedQueue<T>& LinkedQueue<T>::Delete(T& x)
3. {
4. if (IsEmpty()) throw OutOfBounds();
5. // menyimpan data elemen terdepan
6. x = front->data;
7. // menghapus elemen pertama
8. Node<T> *p = front;
9. front = front->link;
10. delete p;
11. return *this;
12. }

Oleh karena penambahan elemen dilakukan di belakang, maka penghapusan


elemen dilakukan pada elemen pertama (sifat dari queue). Elemen yang dihapus yaitu x
juga bisa digunakan oleh fungsi lain. Ini terlihat dari parameter yang mengijinkan
adanya perubahan dari yang tadinya belum ada, lalu di-assign (4) elemen yang dihapus
yaitu x (2).
Cara menghapus dilakukan sebagai berikut. Pointer p diminta menunjuk elemen
pertama (6). Pointer p akan digunakan sebagai tempat yang akan dihapus (8). Pointer
front digeser ke elemen kedua (7). Lalu memori dibebaskan (8). Queue dengan elemen
yang sudah dihapus dikembalikan (10).

Program 6.16. Main function untuk mencoba ADT queue


1. #include <iostream.h>
2. #include "lqueue.h"
3. void main(void)
4. {
5. LinkedQueue<int> Q;
6. int x;
7.
8. Q.Add(1).Add(2).Add(3).Add(4);
9. cout << "No queue add failed" << endl;
10. cout << "Queue is now 1234" << endl;
11. Q.Delete(x);

Bab 9 Antrian halaman 125


12. cout << "Deleted " << x << endl;
13. cout << Q.First() << " is at front" << endl;
14. cout << Q.Last() << " is at end" << endl;
15.
16. Q.Delete(x);
17. cout << "Deleted " << x << endl;
18. Q.Delete(x);
19. cout << "Deleted " << x << endl;
20. Q.Delete(x);
21. cout << "Deleted " << x << endl;
22. cout << "No queue delete failed " << endl;
23. }

Q merupakan objek dari antrian (5). Ditambahkan secara berturut-turut elemen 1,


2, 3, dan 4 ke antrian Q (8). Jika berhasil komentar (9) dicetak. Penghapusan pertama
kali dilakukan (11), dalam hal ini elemen 1 akan dikeluarkan dari antrian. Dengan
demikian elemen 2 pada posisi terdepan (13) sedangkan elemen 4 pada posisi paling
belakang (14). Kemudian dilakukan penghapusan 3 kali berturut-turut hingga antrian
kosong. (16, 18 dan 20).

D. Aplikasi Antrian

Deskripsi Masalah

Suatu bengkel terdiri dari m mesin. Setiap mesin mengerjakan pekerjaan tertentu,
dan setiap pekerjaan terdiri dari tugas-tugas tertentu. Setiap mesin dapat memproses satu
tugas dari satu pekerjaan pada satu waktu, sedangkan mesin yang berbeda mengerjakan
tugas yang berbeda pula. Sekali suatu mesin mulai memproses suatu tugas, dia
melanjutkan memproses tugas sampai tugas tersebut selesai.

Contoh :

Bab 9 Antrian halaman 126


Suatu lembaran logam akan mempunyai satu mesin untuk tugas berikut :
rancangan, memotong lembaran sesuai ukuran yang dibutuhkan, melobangi, memotong
lobang, menggarisi pinggiran, membentuk dan menyegel lapisan. Setiap mesin dapat
mengerjakan satu tugas pada satu waktu.
Untuk setiap tugas dari suatu pekerjaan tertentu, akan diselesaikan pada waktu
tertentu (task time) oleh mesin tertentu. Tugas ini akan dikerjakan dengan urutan
tertentu. Dengan demikian, tugas pertama akan diselesaikan oleh suatu mesin (sampai
selesai), baru dilanjutkan tugas kedua oleh mesin kedua, dan seterusnya sampai tugas
tersebut lengkap dikerjakan. Bila pekerjaan datang pada suatu mesin, bisa jadi pekerjaan
itu harus menunggu karena mesin sedang sibuk.
Setiap mesin mempunyai 3 fase : aktif, idle (menganggur) dan ganti tugas. Pada
fase aktif, mesin mengerjakan tugas dari beberapa pekerjaan, pada fase idle, dia tidak
mengerjakan sesuatu, dan pada fase ganti tugas mesin telah melengkapi suatu tugas dan
akan mempersiapkan untuk mengerjakan tugas baru. Pada fase ganti tugas ini, seorang
operator bisa membersihkan mesin, mengganti peralatan dari tugas terakhir dengan
peralatan lain untuk tugas yang baru, dan sebagainya.
Ketika mesin telah tersedia untuk melakukan pekerjaan baru, dia perlu untuk
mengambil pekerjaan yang telah menunggu. Dalam bengkel kita ini, setiap mesin
mengambil pekerjaan yang menunggu tadi dengan aturan FIFO (First In First Out : yang
pertama datang akan dilayani lebih dulu) yang membentuk antrian. Bisa terjadi pada
bengkel lain akan memberlakukan urutan pekerjaan sesuai dengan prioritas. Sehingga
ketika mesin siap mengerjakan tugas baru, dia akan mengambil pekerjaan dengan
prioritas tertinggi.
Waktu mesin selesai mengerjakan tugas dinamakan finish time. Lama waktu dari
suatu pekerjaan adalah jumlah kumulatif waktu dari tugas-tugasnya. Jika pekerjaan
lamanya L datang pada mesin saat waktu 0 dan selesai pada waktu f, maka

Bab 9 Antrian halaman 127


pekerjaan tersebut harus menunggu selama f - L. Untuk menjaga agar pelanggan tetap
senang, kita harus meminimalkan waktu tunggu ini.
Pertimbangkanlah sebuah bengkel yang mempunyai m = 3 mesin dan n = 6
pekerjaan. Diasumsikan semua mesin tersedia pada awal waktu t = 0 dan tidak ada
pekerjaan baru selama simulasi. Simulasi akan berlanjut sampai semua pekerjaan
lengkap dikerjakan.
Ada 3 mesin, namakan M1, M2, dan M3 masa tukar berturut-turut 2, 0 dan 1,
sehingga ketika tugas selesai, mesin 1 harus menunggu 2 unit waktu sebelum memulai
yang lain, mesin 2 langsung dapat mulai mengerjakan tugas berikutnya langsung, dan
mesin 3 harus menunggu 1 unit waktu. Tabel berikut memberikan karakteristik dari 4
pekerjaan tersebut :

Nomor Pekerjaan Banyaknya tugas Tugas Total waktu

1 3 (1,2) (2,4) (1,1) 7

2 2 (3,4) (1,2) 6

3 2 (1,4) (2,4) 8

4 2 (3,1) (2,3) 4

Pekerjaan nomor 1, misalnya mempunyai 3 tugas. Setiap tugas disimbolkan


sebagai pasangan berbentuk (mesin, waktu). Tugas pertama dari pekerjaan 1 dikerjakan
pada M1 dan memerlukan waktu 2 unit, tugas kedua dikerjakan M2 yang memerlukan
waktu 4 unit, dan tugas ketiga dikerjakan pada M1 yang memerlukan waktu 1 unit.
Berikut ini adalah tabel simulasi mesin bengkel.

Waktu Antrian Mesin Pekerjaan Waktu Selesai

Bab 9 Antrian halaman 128


Aktif
M1 M2 M3 M1 M2 M3 M1 M2 M3
Init 1,3 - 2,4 I I I L L L
0 3 - 4 1 I 2 2 L 4
2 3 - 4 C 1 2 4 6 4
4 2 - 4 3 1 C 8 6 5
5 2 - - 3 1 4 8 6 6
6 2,1 4 - 3 C C 8 9 7
7 2,1 4 - 3 C I 8 9 L
8 2,1 4,3 - C C I 10 9 L
9 2,1 3 - C 4 I 10 12 L
10 1 3 - 2 4 I 12 12 L
12 1 3 - C C I 14 15 L
14 - 3 - 1 C I 15 15 L
15 - - - C 3 I 17 16 L
16 - - - C C I 19 19 L

Implementasi dari Deskripsi masalah di atas menggunakan kelas Machine berikut


ini.

Program 6.17. Kelas Machine untuk simulasi mesin


1. class Machine {
2. friend Job* ChangeState(int);
3. public:
4. Machine() {TotalWait = NumTasks = 0;
5. Active = 0;}
6. bool IsEmpty() {return JobQ.IsEmpty();}
7. void AddJob(Job* x) {JobQ.Add(x);}
8. void SetChange(long w) {ChangeTime = w;}
9. void Stats(long& tw, long& nt)
10. {tw = TotalWait;
11. nt = NumTasks;}
12. private:
13. LinkedQueue<Job*> JobQ; // queue of waiting jobs
14. long ChangeTime; // machine changeover time

Bab 9 Antrian halaman 129


15. long TotalWait; // total delay at this machine
16. long NumTasks; // number of tasks processed
17. Job *Active; // pointer to current job
18. };

Data member dari kelas Machine ada 5 yaitu JobQ untuk menampung antrian
pekerjaan yang sedang menunggu, ChangeTime untuk menyimpan waktu bertukar
mesin, TotalWait untuk menyimpan total waktu tunda mesin, NumTasks menunjukkan
banyaknya tugas yang diproses, dan pointer Active yang digunakan untuk menunjuk
pekerjaan saat ini.
Konstruktor mengawali Machine dengan total waktu tunda sama dengan 0 dan
banyaknya tugas sama dengan 0 (4), sedangkan Active tidak menunjuk ke manapun (5).

Program 6.18. Kelas Task untuk penjadwalan mesin


1. class Task {
2. friend class Job;
3. friend bool MoveToNextMachine(Job*);
4. private:
5. long time;
6. int machine;
7. };

Bab 9 Antrian halaman 130


Program 6.19. Kelas Job
1. class Job {
2. friend bool MoveToNextMachine(Job*);
3. friend Job* ChangeState(int);
4. friend void Simulate();
5. friend class Machine;
6. public:
7. Job(long id) {ID = id;
8. Length = ArriveTime = 0;}
9. void AddTask(int p, long t) {
10. Task x;
11. x.machine = p;
12. x.time = t;
13. TaskQ.Add(x);}
14. long DeleteTask() {// delete next task
15. Task x;
16. TaskQ.Delete(x);
17. Length += x.time;
18. return x.time;}
19. private:
20. LinkedQueue<Task> TaskQ;
21. long Length;
22. long ArriveTime;
23. long ID;
24. };

Kelas Job mempunyai 4 data member, yaitu TaskQ yang digunakan untuk
menyimpan antrian tugas, Length digunakan untuk menyimpan jumlah waktu tugas yang
dijadwalkan, ArriveTime digunakan untuk menyimpan waktu kedatangan pada antrian
saat ini, dan ID yang digunakan untuk menyimpan identifier pekerjaan.
Konstruktor kelas Job, menginisialisasi pekerjaan dengan id (7) sementara lama
pekerjaan Length dan waktu kedatangan diset 0 (8). Method AddTask

Program 6.20. Kelas EventList

Bab 9 Antrian halaman 131


1. class EventList {
2. public:
3. EventList(int m, long BigT);
4. ~EventList(){delete [] FinishTime;}
5. void NextEvent(int& p, long& t);
6. long NextEvent(int p) {return FinishTime[p];}
7. void SetFinishTime(int p, long t)
8. {FinishTime[p] = t;}
9. private:
10. long *FinishTime; // finish time array
11. int NumMachines; // number of machines in shop
12. };

Program 6.21. Konstruktor kelas EvenList


1. EventList::EventList(int m, long BigT)
2. {
3. FinishTime = new long [m+1];
4. NumMachines = m;
5. for (int i = 1; i <= m; i++)
6. FinishTime[i] = BigT;
7. }

Pertama kali m mesin diinisialisasi waktu selesainya dengan cara memberikan


angka yang besar untuk FinishTime (6). Pemesanan memori ditambah dengan 1 (3)
karena elemen ke-nol tidak akan dipakai. Jadi untuk menampung banyaknya mesin
sebanyak m diperlukan memori sebesar m+1.

Program 6.22. Method NextEvent


1. void EventList::NextEvent(int& p, long& t)
2. {
3. p = 1;
4. t = FinishTime[1];
5. for (int i = 2; i <= NumMachines; i++)
6. if (FinishTime[i] < t) {// i finishes earlier
7. p = i;

Bab 9 Antrian halaman 132


8. t = FinishTime[i];}
9. }

Untuk berbagai macam keperluan, diperlukan deklarasi variabel global berikut

ini.

Program 6.23. Deklarasi variabel global


1. long Now = 0; // current time
2. int m; // number of machines
3. long n; // number of jobs
4. long LargeTime = 10000; // finish before this time
5. EventList *EL; // pointer to event list
6. Machine *M; // array of machines

// Move J to machine for next task.


// Return false if no next machine for this job.
1. bool MoveToNextMachine(Job *J)
2. {
3. if (J->TaskQ.IsEmpty()) {// no next task
4. cout << "Job " << J->ID << " has completed at "
5. << Now << " Total wait was " << (Now-J->Length) << endl;
6. return false;}
7. else {// job has a next task
8. // get machine for next task
9. int p = J->TaskQ.First().machine;
10. // put on p's wait queue
11. M[p].AddJob(J);
12. J->ArriveTime = Now;
13. // if p idle, schedule immediately
14. if (EL->NextEvent(p) == LargeTime) {// machine is idle
15. ChangeState(p);}
16. return true;}
17. }
18.

Bab 9 Antrian halaman 133


// Task on machine p has finished, schedule next one.
// Return last job.
1. Job* ChangeState(int p)
2. {
3. Job* LastJob;
4. if (!M[p].Active) {// in idle or change-over state
5. LastJob = 0;
6. // wait over, ready for new job
7. if (M[p].JobQ.IsEmpty()) // no waiting job
8. EL->SetFinishTime(p,LargeTime);
9. else {// take job off Q and work on it
10. M[p].JobQ.Delete(M[p].Active);
11. M[p].TotalWait += Now - M[p].Active->ArriveTime;
12. M[p].NumTasks++;
13. long t = M[p].Active->DeleteTask();
14. EL->SetFinishTime(p, Now + t);}
15. }
16. else {// task has just finished on M[p]
17. // schedule change-over time
18. LastJob = M[p].Active;
19. M[p].Active = 0;
20. EL->SetFinishTime(p, Now + M[p].ChangeTime);}
21. return LastJob;
22. }

Bab 9 Antrian halaman 134


// Input machine shop data.
1. void InputData()
2. {
3. cout << "Enter number of machines and jobs" << endl;
4. cin >> m >> n;
5.
6. // create event and machine queues
7. EL = new EventList(m,LargeTime);
8. M = new Machine [m+1];
9. // input the machine wait times
10. cout << "Enter change-over times for machines" << endl;
11. for (int j = 1; j <= m; j++) {
12. long ct; // change-over time
13. cin >> ct;
14. M[j].SetChange(ct);
15. }
16. // input the n jobs
17. Job *J;
18. for (int i = 1; i <= n; i++) {
19. cout << "Enter number of tasks for job " << i << endl;
20. int tasks; // number of tasks
21. int first; // machine for first task of job
22. cin >> tasks;
23.
24. J = new Job(i);
25. cout << "Enter the tasks (machine, time)"
26. << " in process order" << endl;
27. for (int j = 1; j <= tasks; j++) {// get tasks
28. int p; // machine number
29. long tt; // task time
30. cin >> p >> tt;
31. if (j == 1) first = p; // job's first machine
32. J->AddTask(p,tt); // add task to task queue
33. }
34. M[first].AddJob(J); // add job to machine for
35. } // first task
36. }

Bab 9 Antrian halaman 135


Mengembalikan elemen puncak stack
1. void StartShop()
2. {// Load first jobs onto each machine.
3. for (int p = 1; p <= m; p++)
4. ChangeState(p);
5. }

// Process all n jobs to completion.


1. void Simulate()
2. {
3. int p;
4. long t;
5. while (n) {// at least one job left
6. EL->NextEvent(p,t); // next machine to finish
7. Now = t; // present time
8. // change job on machine p
9. Job *J = ChangeState(p);
10. // move job J to its next machine
11. // decrement n if J has finished
12. if (J && !MoveToNextMachine(J)) n--;
13. }
14. }

// Output wait times at machine.


1. void OutputStats()
2. {
3. cout << "Finish time = " << Now << endl;
4. long TotalWait, NumTasks;
5. for (int p = 1; p <= m; p++) {
6. M[p].Stats(TotalWait, NumTasks);
7. cout << "Machine " << p << " completed "
8. << NumTasks << " tasks" << endl;
9. cout << "The total wait time was " << TotalWait;
10. cout << endl << endl;
11. }
12. }

Bab 9 Antrian halaman 136


Fungsi main untuk menjalankan simulasi
1. void main(void)
2. {// Machine shop simulation.
3. InputData(); // get machine and job data
4. StartShop(); // initial machine loading
5. Simulate(); // run all jobs through shop
6. OutputStats(); // output macine wait times
7. }

Bab 9 Antrian halaman 137


SKENARIO PERKULIAHAN MINGGU 10

Persiapan [50 menit]

01. Mahasiswa mengerjakan Pretest Praktikum


02. Mahasiswa mempelajari Antrian Berprioritas
03. Mahasiswa membuat contoh Antrian Berprioritas
04. Catatan :
a. Boleh belajar bersama kelompok masing-masing

b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]

00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing

01. Dosen membuka perkuliahan


02. Dosen memberikan contoh Antrian Berprioritas
03. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
04. Dosen menjelaskan pembuatan Antrian Berprioritas
05. Mahasiswa mengikuti dengan compilernya masing-masing
06. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]

01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya masing-


masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]

01. Dosen memberikan rangkuman materi kuliah minggu ini


02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 10 Antrian Berprioritas halaman 138


Bab X
Antrian Berprioritas
Tujuan pembelajaran:

1. Mahasiswa mampu menganalisis letak elemen baru berdasarkan prioritasnya


2. Mahasiswa mampu menerapkan prinsip prinsip antrian berprioritas dalam sebuah
bahasa pemrogaman

Mari kita perhatikan contoh contoh berikut ini :

Kasus 1

Pada sebuah tempat fotokopi seorang mahasiswa akan memfotokopi satu lembar ktp nya.
Pegawai fotocopy saat itu sedang mengerjakan setumpuk pesanan (terlihat beberapa buku
yang akan di fotocopi) bila menggunakan urutan antrian biasa maka sang mahasiswa harus
menunggu semua buku slesai di fotocopy oleh pegawai itu. Yang terjadi, pegawai fotokopi
meminta ktp dan memfotocopi kt itu

Kasus 2

Di sebuah loket penjualan tiket kereta api berderet antrian cukup panjang calon penumpang
untuk membeli tiket. Datang lah seorang difabel menggunakan kursi roda ikut mengantri di
belakang sesuai dengan antrian biasa. Tiba tiba satpam menghampiri kemudian
mengantarkan orang difabel itu menuju depan loket untuk mendapat layanan pebelian tiket
lebih dulu dari pada yang lain

Kedua kasus di atas memberikan gambaran bahwa untuk kondisi tertentu suatu antrian bisa
memiliki karakter khusus dimana pengantri bisa memperoleh layanan lebih dulu walaupun
datangnya belakangan. Sebutan dari fenomena ini pengantri yang mendapat prioritas ini
memenuhi kaidah antrian berpriotas

Dengan demikian karakteristik antrian berpriotas adalah sebagai berikut:

1. Elemen yang paling depan akan di layani lebih dulu. Elemen berikutnya di layani
mengikuti urutan dari antrian

Bab 10 Antrian Berprioritas halaman 139


2. Setiap ada elemen baru yang akan masuk antrian maka elemen itu akan menempati
posisi sesuai dengan prioritas nya. Dengan demikian antrian yang ada akan terurut
pelayanan nya berdasarkan prioritas
3. Dari poin 1 dan 2 sifat antrian tetap di pertahankan yaitu first in first out dalam hal ini
yang di katakan pertama masuk adalah yang memiliki prioritas tertinggi. Arti first out
adalah yang di layani lebih dulu.

Dalam bab ini akan di bahas aspek logika dari antrian berprioritas menggunakan array 1
dimensi

Misalkan kita memiliki antrian berisi 4 elemen. Perhatikan dalam antrian ini isi array
mewakili prioritas. Elemen yang lebih kecil akan memiliki prioritas lebih tinggi atau (lebih
dulu) di layani

Isi array 2 5 8 9
indeks 0 1 2 3
Gambar 10.1 Array dengan 4 elemen

Misalkan kita akan memasukan elemen baru yaitu 10. Maka elemen ini akan di bandingkan
dengan elemen dari indeks 0 sampai pada posisi yang tepat yaitu berada di belakang elemen
yang paling besar di dalam antrian. Pada gambar 10.1, elemen 10 ini berada di belakang
elemen 9 (elemen terbesar dalam array) berikut ini:

Isi array 2 5 8 9 10
indeks 0 1 2 3 4
Gambar 10.2 Array dengan 5 elemen setelah di tambah elemen 10 indeks 4

Bagaimana jika elemen yang baru adalah elemen 7 ?

Mari kita bandingkan mulai dari elemen indeks 0. Ternyata 2 lebih kecil dari 7 bukan disini
tempatnya. Kita cek kembali dengan elemen berikutnya yaitu elemen 5. Sekali lagi di
temukan 5 masih lebih kecil dari 7 jadi 7 bukan pula tempatnya di indeks 1. Kita ulangi lagi
perbandingan pada elemen berikutnya (indeks 2) ternyata 8 tidak lebih kecil dari 7 maka
sudah di temukan tempat bagi elemen 7 yaitu pada indeks 2.

Lalu bagaimana elemen dari posisi indeks 3 dan elemen selanjutnya ?

Untuk itu elemen dari indeks 2 sampai elemen terakhir di geser satu tempat ke kanan (posisi
indeks di tambah 1). Artinya :
Bab 10 Antrian Berprioritas halaman 140
Elemen 10 indeks 4 akan di tempatkan pada indeks 5. Elemen 9 indeks 3 akan di tempatkan
pada indeks 4. Elemen 8 indeks 2 akan di tempatkan pada indeks 3.

Langkah terakhir elemen 7 akan di tempatkan pada indeks 2 sebagai berikut:

Isi array 2 5 7 8 9 10
indeks 0 1 2 3 4 5
Gambar 10.3 Array dengan 6 elemen setelah di tambah elemen 7 pada indeks 2

Untuk itu dari gambar 10.3 itu saat menambah elemen di perlukan suatu fungsi yang
algoritma nya atau langkah langkah nya sebagai berikut:

1. Saat elemen x di masukan maka elemen ini akan mencari posisi yang tepat sesuai
dengan prioritas nya. Dari gambar 10.3, posisi tepat itu artinya posisi indeks
sebelumnya namakan a, isi nya lebih kecil (a<x) dan isi dari indeks setelahnya
namakan b lebih besar dari elemen baru itu (b>x). Catat posisi nya adalah p
2. Lakukan pergeseran elemen ke kanan (berarti indeks nya bertambah 1) untuk setiap
elemen dari posisi p sampai indeks terakhir
3. Tempatkan elemen x pada indeks p

Menghapus elemen antrian berprioritas

Menghapus elemen berprioritas sama karakteristik nya dengan menghapus elemen antrian
biasa. Dalam kasus antrian berprioritas, dengan asumsi elemen terkecil akan di layani lebih
dulu (keluar antrian lebih dulu) maka elemen pertama (indeks 0) yang akan di keluarkan dari
antrian. Langkah nya adalah sebagai berikut:

1. Geser ke kiri (indeks berkurang 1) mulai dari indeks 1 sampai indeks terakhir
2. Perlu di perhatikan akan ada elemen ganda yaitu elemen indeks terakhir masih ada
yang sama dengan indeks sebelumnya. Sebagai contoh:

Isi array 2 5 7 8 9 10
indeks 0 1 2 3 4 5
Gambar 10.4 Array dengan 6 elemen setelah di tambah elemen 7 pada indeks 2

Bab 10 Antrian Berprioritas halaman 141


Dari gambar 10.4, 2 di keluarkan dari antrian. Maka akan di geser elemen mulai dari
posisi 1 sampai akhir (indeks 5), antrian akan menjadi seperti berikut:

Isi array 5 7 8 9 10 10
indeks 0 1 2 3 4 5
Gambar 10.5 Array 6 elemen dengan duplikat elemen

Terlihat indeks 4 dan indeks 5 sama elemen nya. Ingat setelah keluar dari antrian, antrian
berprioritas yang tadi nya 6 elemen menjadi 5 elemen. Maka kita hanya memerlukan akses
dari indeks 0 sampai indeks 4 (5 elemen). Anggap saja gambar logic nya adalah sebagai
berikut:

Isi array 5 7 8 9 10 x
indeks 0 1 2 3 4 x
Gambar 10.6 Array setelah di kurangi 1 elemen

Dengan x adalah elemen yang “kosong”, artinya elemen itu tidak perlu di akses.

Diskusi

1. Diskusikan algoritma menggeser 1 elemen dari posisi x sampai akhir indeks array lalu
buatlah fungsinya
2. Diskusikan menggeser 1 elemen ke kiri dari posisi x sampai n-1 (n adalah maksimum
jumlah elemen array awal). Jumlah elemen yang bisa di akses setelah bergeser 1
elemen berjumlah n-1 elemen

Bab 10 Antrian Berprioritas halaman 142


SKENARIO PERKULIAHAN MINGGU 11

Persiapan [50 menit]


01. Mahasiswa mengerjakan Pretest Praktikum
02. Mahasiswa mempelajari Struktur Data Pohon
03. Mahasiswa mencari contoh program Struktur Data Pohon
04. Catatan :
a. Boleh belajar bersama kelompok masing-masing
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]


00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing
01. Dosen membuka perkuliahan
02. Dosen menjelaskan definisi dan konstruksi Struktur Data Pohon
03. Dosen memberikan contoh Struktur Data Pohon
04. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
05. Dosen menjelaskan pembuatan Struktur Data Pohon
06. Mahasiswa mengikuti dengan compilernya masing-masing
07. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok
memilih tugasnya masing-masing

Kegiatan Diskusi [20 menit]


01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya
masing-masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]


01. Dosen memberikan rangkuman materi kuliah minggu ini
02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 11 Pohon halaman 143


Bab XI

Pohon

A. Pendahuluan
 Struktur data pohon merupakan struktur data tak linier
 Struktur data pohon menggambarkan hubungan yang bersifat hirarkis,
misalnya silsilah keluarga, struktur organisasi.

rektor

PR I PR II PR III

PD I Kajur PD II Bendahara PD III

Gambar 8.1. Struktur Hirarki Organisasi Perguruan Tinggi


Istilah-istilah :

 Pohon : kumpulan elemen, salah satunya berupa akar (root) yang lain berupa
cabang (subpohon) di mana antara cabang satu dengan yang lain tidak saling
berhubungan
 Pohon (didefinisikan secara rekursif) :

 Sebuah node tunggal adalah pohon

 Jika terdapat sebuah node N dan subpohon T 1, T2, …, Tk yang saling


tidak berhubungan, dan berakar pada N1, N2, …, Nk, maka dari node N
dan subpohon-subpohon ini dapat dibentuk sebuah pohon pada node N.

N N

N1 N2 Nk N1 N2 Nk

 Node : elemen pohon yang berisi informasi dan penunjuk percabangan

Bab 11 Pohon halaman 144


 Tingkat (level) : akar ditentukan bertingkat 1

 Derajat (degree) : banyaknya turunan dari suatu node.


Contoh : A berderajat 4, B berderajat 2.
 Daun (leaf) : node yang berderajat 0, dinamakan juga sebagai node eksternal.
Node lain selain akar disebut node internal.

Tingkat/level

1 H

2 A K

3 C J L

4 B D

Gambar 8.2. Tingkat dari sebuah pohon

 Tinggi (high) / kedalaman (depth) : tingkat maksimum node dalam pohon


dikurangi 1, misalnya depth(A) = 4.
 Anchestor suatu node yang terletak dalam satu jalur dengan node tersebut dari
akar sampai node yang ditinjau.
Contoh :

Anchestor(L) = A, C, G

 Hutan (forest) : kumpulan pohon yang saling tidak berhubungan. Bila A


dihapus akan diperoleh hutan.
 Pohon beraturan (ordered tree) : urutan hubungan satu node dengan node lain
diperhatikan.
Contoh :

Dua pohon berikut adalah dua pohon yang berbeda .

A A

B C D D C D

Bab 11 Pohon halaman 145


Gambar 8.3. Pohon Terurut
Cara lain penyajian pohon adalah dengan diagram

A
C B
G
E
F L
J K

M
H
D
N O
I

Gambar 8.7. Diagram Venn untuk merepresentasikan pohon


Venn.

Gambar 8.4. Diagram Venn Untuk Pohon


Atau dengan notasi kurung :
(A (B (D (I), E(J,K), C(F, G(L, M(N, O)), H)))

Bab 11 Pohon halaman 146


Atau dengan notasi tingkat bergaris :
A

Gambar 8.5. Notasi tingkat bergaris dari suatu pohon

B. Pohon biner (Binary Tree)

 Pohon biner (Binary Tree) yaitu kumpulan node yang paling banyak (bisa
kosong atau satu) mempunyai 2 subpohon yaitu subpohon kiri (left
subtree/cabang kiri) dan subpohon kanan (right subtree/cabang kanan).
 Pohon biner lengkap (complete binary tree) bertingkat N adalah suatu pohon
biner yang semua daunnya terdapat pada tingkat N, dan semua node internal
mempunyai 2 cabang. Sebagai contoh :

Bab 11 Pohon halaman 147


A

B C

D E F G

Gambar 8.6. Pohon Biner Lengkap tingkat 3

C. Pohon biner miring (skewed binary tree)


Pohon biner miring adalah pohon biner di mana banyaknya node cabang kiri
tidak seimbang dengan banyaknya node cabang kanan. Di bawah ini contoh pohon
biner miring ke kiri dan miring ke kanan.

A A

B B

C C

D D

Gambar 8.7. Pohon Gambar 8.8. Pohon


Biner Miring ke kiri Biner Miring ke kanan

Banyaknya node maksimum pada tingkat N adalah 2(N-1) sehingga banyaknya node
maksimum pada tingkat N adalah :
N

i=1
2(i-1) =2N -1

dengan demikian suatu pohon biner lengkap bertingkat 5, banyaknya daun adalah 16
dan banyaknya node yang bukan daun (termasuk akar) adalah 15 .

Bab 11 Pohon halaman 148


D. Deklarasi Pohon
Setiap node dalam pohon disajikan sebagai :

LeftChild data RightChild

Sehingga deklarasi node yang sesuai dengan gambar logik di atas adalah :
class BinaryTreeNode {
private
T data;
BinaryTreeNode<T> *LeftChild, *RightChild;
}

Asumsi :
Node dengan informasi lebih besar dari node induk ditaruh pada cabang
kanan, bila lebih kecil ditaruh di cabang kiri.
Contoh :
Untuk untai data H K A C B L J pohon binernya adalah :

A K

C J L

Gambar 8.9. Pohon biner untai data


Tipe data abstrak selengkapnya adalah sebagai berikut :
Program 7.1. Kelas BinaryTreeNode (File btnode1.h)
1. template <class T> class BinaryTree;
2. template <class T>
3. class BinaryTreeNode {
4. friend void Visit(BinaryTreeNode<T> *);
5. friend void InOrder(BinaryTreeNode<T> *);

Bab 11 Pohon halaman 149


6. friend void PreOrder(BinaryTreeNode<T> *);
7. friend void PostOrder(BinaryTreeNode<T> *);
8. friend void LevelOrder(BinaryTreeNode<T> *);
9. friend void main(void);
10. public:
11. BinaryTreeNode() {LeftChild = RightChild = 0;}
12. BinaryTreeNode(const T& e)
13. {data = e;
14. LeftChild = RightChild = 0;}
15. BinaryTreeNode(const T& e, BinaryTreeNode *l,
16. BinaryTreeNode *r)
17. {data = e;
18. LeftChild = l;
19. RightChild = r;}
20. private:
21. T data;
22. BinaryTreeNode<T> *LeftChild,
23. *RightChild;
24. };

Kelas BinaryTreeNode mempunyai 3 data member yaitu, data untuk


menyimpan informasi (21), pointer LeftChild untuk menunjuk cabang kiri (22), dan
pointer RightChild untuk menunjuk cabang kanan (23).
Konstruktor kelas BinaryTreeNode menginisialisasi setiap node tanpa cabang
bila belum ada informasi yang disimpan (11), dan (12) bila terdapat informasi yang
akan disimpan yaitu e. Sedangkan konstruktor ketiga (15) digunakan untuk
menyambung node ke pohon biner dengan informasi e (17) sementara pointer
LeftChild menunjuk l (18), dan pointer RightChild menunjuk r (19).

E. Kunjungan pada pohon biner

 Kunjungan dilakukan pada setiap node tepat satu kali (binary tree traversal)

 Dilakukan secara lengkap diperoleh urutan informasi secara linier

 Kunjungan dilakukan dengan cara :

 Preorder

 Inorder

Bab 11 Pohon halaman 150


 Postorder
 Level order
Asumsi :
Kunjungan dilakukan dengan LEFT TO RIGHT ORIENTED (LRO) kunjungan
ke cabang kiri dilakukan lebih dulu.

E.1. Kunjungan PREORDER

 Disebut juga depth first order


 Urutan kunjungan :
1. Cetak isi node yang dikunjungi

2. Kunjungi cabang kiri

3. Kunjungi cabang kanan


Contoh :

B C

D E F

? G H I

Gambar 8.10. Kunjungan secara Preorder


 Hasil kunjungan :
ABDGCEHIF
 implementasi secara non rekursif dengan menggunakan STACK

Contoh running :
1) H

A K

C J L

Bab 11 Pohon halaman 151


2) 6)

3) 7) 8)

4) 5)

Gambar 8.11. Kunjungan Secara Preorder

 Hasil kunjungan :

HACBDKJL

E.2. Kunjungan INORDER

 Kunjungan INORDER disebut juga kunjungan symmetric order

 Urutan kunjungan :

 Kunjungi cabang kiri

 Cetak isi node yang dikunjungi

 Kunjungi cabang
kanan Urutan langkah non rekursif
:
1. Masukkan akar ke stack, bergerak ke cabang kiri

2. Ulangi hingga cabang kiri kosong

3. Pop elemen teratas, cetak isinya

4. Bergerak ke cabang kanan

5. Loop langkah dari awal sampai isi stack kosong

Bab 11 Pohon halaman 152


Contoh :
5)
H

1) A 7) K

3) C 6) J 8) L

B D
2) 4)

Gambar 8.12. Kunjungan Secara Inorder

 Hasil kunjungan INORDER :


ABCDHJKL

E.3. Kunjungan POSTORDER


 Urutan kunjungan :
 Kunjungi cabang kiri
 Kunjungi cabang kanan
 Cetak isi node yang dikunjungi
Contoh :
H

A K

C J L

B D

Gambar 8.13. Kunjungan Secara Postorder


 Hasil kunjungan POSTORDER :
BDCAJLKH

Bab 11 Pohon halaman 153


E.4. Kunjungan LEVEL ORDER

 Kunjungan dimulai dari node yang ada pada tingkat 1 (akar), seterusnya pada
tingkat berikutnya dari kiri ke kanan
 Hasil kunjungan pohon di atas : H A K C J L B D

 Hanya bisa diimplementasikan secara non rekursif dengan menggunakan


antrian (queue)
Algoritma :

1. Akar masuk antrian, lalu dikeluarkan

2. Cabang kiri dan cabang kanan masuk antrian

3. Jadi setiap dikeluarkan dari antrian, cabang kiri dan cabang kanan masuk
antrian

#include
<iostream.h>
#include "lqueue.h"
#include "btnode1.h"
#include "bool.h"

// Visit node *x, just output data field.


1. template <class T>
2. void Visit(BinaryTreeNode<T> *x)
3. {
4. cout << x->data << ' ';
5. }

Method Visit digunakan untuk mencetak elemen node (4).

// Preorder traversal of *t.

Bab 11 Pohon halaman 154


1. template <class T>
2. void PreOrder(BinaryTreeNode<T> *t)
3. {
4. if (t) {
5. Visit(t); // visit tree root
6. PreOrder(t->LeftChild); // do left subtree
7. PreOrder(t->RightChild); // do right subtree
8. }
9. }

Bab 11 Pohon halaman 155


Penelusuran PreOrder dilakukan secara rekursif dengan urutan :
a. Cetak isi node (5)

b. Kunjungi anak kiri sampai habis (6)

c. Kunjungi anak kanan sampai habis (7)

// Inorder traversal of *t.


1. template <class T>
2. void InOrder(BinaryTreeNode<T> *t)
3. {
4. if (t) {
5. InOrder(t->LeftChild); // do left subtree
6. Visit(t); // visit tree root
7. InOrder(t->RightChild); // do right subtree
8. }
9. }

Penelusuran InOrder dilakukan secara rekursif dengan urutan :


a. Kunjungi anak kiri sampai habis (5)

b. Cetak isi node (6)

c. Kunjungi anak kanan sampai habis (7)

// Postorder traversal of *t.


1. template <class T>
2. void PostOrder(BinaryTreeNode<T> *t)
3. {
4. if (t) {
5. PostOrder(t->LeftChild); // do left subtree
6. PostOrder(t->RightChild); // do right subtree
7. Visit(t); // visit tree root
8. }
9. }

Penelusuran PostOrder dilakukan secara rekursif dengan urutan :


a. Kunjungi anak kiri sampai habis (5)

b. Kunjungi anak kanan sampai habis (6)

c. Cetak isi node (7)

Bab 11 Pohon halaman 156


// Level-order traversal of *t.
1. template <class T>
2. void LevelOrder(BinaryTreeNode<T> *t)
3. {
4. LinkedQueue<BinaryTreeNode<T>*> Q;
5. while (t) {
6. Visit(t);
7. if (t->LeftChild) Q.Add(t->LeftChild);
8. if (t->RightChild) Q.Add(t->RightChild);
9.
10. try {Q.Delete(t);}
11. catch (OutOfBounds) {return;}
12. }
13. }

Penelusuran LevelOrder tidak dapat dilakukan secara rekursif namun


menggunakan antrian Q (4). Pernyataan while (5) sampai dengan (11) akan
dieksekusi selama pohon belum kosong. Kondisi a wal, akar dikunjungi atau dicetak
informasinya (6). Setelah mencetak elemen akar, elemen pada cabang kiri dan
cabang kanan masuk antrian (7) dan (8). Jadi, setiap kali sudah dicetak
informasinya, elemen akan dihapus dari antrian (keluar antrian) (10) dan dicetak
elemennya (6), cabang kiri dan cabang kanan masuk antrian (7 dan 8). Begitu
seterusnya sampai semua elemen dari pohon telah dikunjungi.
Uji coba dilakukan dengan fungsi main berikut.

// create a binary tree with root x


1. void main(void)
2. {
3. BinaryTreeNode<int> x, y, z;
4. x.data = 1;
5. y.data = 2;
6. z.data = 3;
7. x.LeftChild = &y;
8. x.RightChild = &z;
9. y.LeftChild = y.RightChild = z.LeftChild = z.RightChild = 0;
10. // traverse x in all ways
11. cout << "Inorder sequence is ";
12. InOrder(&x);

Bab 11 Pohon halaman 157


13. cout << endl;
14. cout << "Preorder sequence is ";
15. PreOrder(&x);
16. cout << endl;
17. cout << "Postorder sequence is ";
18. PostOrder(&x);
19. cout << endl;
20. cout << "Level order sequence is ";
21. LevelOrder(&x);
22. cout << endl;
23. }

Ada 3 node yang dibuat (3), yaitu x, y, dan z. Node x menyimpan data 1 (4), y
menyimpan data 2 (5), dan z menyimpan data 3 (6). Node x dapat dipandang sebagai
akar dengan cabang kirinya adalah y (7), dan cabang kanannya adalah z (8),
sementara cabang kiri dan cabang kanan node y dan z kosong (9).

// infix.h

1. template <class T>


2. void Infix(BinaryTreeNode<T> *t)
3. {// Output infix form of expression.
4. if (t) {cout << '(';
5. Infix(t->LeftChild); // left operand
6. cout << t->data; // operator
7. Infix(t->RightChild); // right operand
8. cout << ')';}
9. }

// generate infix from expression tree

1. #include <iostream.h>
2.
3. template <class type>
4. class BinaryTreeNode {
5. friend void Infix(BinaryTreeNode<type>*);
6. friend void main(void);
7. private:
8. type data;

Bab 11 Pohon halaman 158


9. BinaryTreeNode *LeftChild, *RightChild;
10. };

1. #include "infix.h"
2.
3. void main(void)
4. {
5. BinaryTreeNode<int> x,y,z;
6. x.data = 1; y.data = 2; z.data = 3;
7. x.LeftChild = &y; x.RightChild = &z;
8. y.LeftChild = y.RightChild = z.LeftChild = z.RightChild = 0;
9. Infix(&x);
10. cout << endl;
11. }

// btnode2.h

1. template <class T> class BinaryTree;


2. template<class E, class K> class BSTree;
3. template<class E, class K> class DBSTree;
4.
5. template <class T>
6. class BinaryTreeNode {
7. friend BinaryTree<T>;
8. friend void PlaceBoosters(BinaryTreeNode<T> *);
9. friend BSTree<T,int>;
10. friend DBSTree<T,int>;
11. public:
12. BinaryTreeNode() {LeftChild = RightChild = 0;}
13. BinaryTreeNode(const T& e)
14. {data = e; LeftChild = RightChild = 0;}
15. BinaryTreeNode(const T& e, BinaryTreeNode *l,
16. BinaryTreeNode *r)
17. {data = e; LeftChild = l; RightChild = r;}
18. private:
19. T data;
20. BinaryTreeNode<T> *LeftChild, // left subtree
21. *RightChild; // right subtree
22. };

Bab 11 Pohon halaman 159


// file binary.h

1. #ifndef BinaryTree_
2. #define BinaryTree_
3. int _count;
4.
5. #include<iostream.h>
6. #include "lqueue.h"
7. #include "btnode2.h"
8. #include "bool.h"
9.
10. template<class E, class K> class BSTree;
11. template<class E, class K> class DBSTree;
12.
13. template<class T>
14. class BinaryTree {
15. friend BSTree<T,int>;
16. friend DBSTree<T,int>;
17. public:
18. BinaryTree() {root = 0;};
19. ~BinaryTree(){};
20. bool IsEmpty() const
21. {return ((root) ? false : true);}
22. bool Root(T& x) const;
23. void MakeTree(const T& element,
24. BinaryTree<T>& left, BinaryTree<T>& right);
25. void BreakTree(T& element, BinaryTree<T>& left,
26. BinaryTree<T>& right);
27. void PreOrder(void(*Visit)(BinaryTreeNode<T> *u))
28. {PreOrder(Visit, root);}
29. void InOrder(void(*Visit)(BinaryTreeNode<T> *u))
30. {InOrder(Visit, root);}
31. void PostOrder(void(*Visit)(BinaryTreeNode<T> *u))
32. {PostOrder(Visit, root);}
33. void LevelOrder(void(*Visit)(BinaryTreeNode<T> *u));
34. void PreOutput() {PreOrder(Output, root); cout << endl;}
35. void InOutput() {InOrder(Output, root); cout << endl;}
36. void PostOutput() {PostOrder(Output, root); cout << endl;}
37. void LevelOutput() {LevelOrder(Output); cout << endl;}
38. void Delete() {PostOrder(Free, root); root = 0;}
39. int Height() const {return Height(root);}
40. int Size()
41. {_count = 0; PreOrder(Add1, root); return _count;}

Bab 11 Pohon halaman 160


42. private:
43. BinaryTreeNode<T> *root; // pointer to root
44. void PreOrder(void(*Visit)
45. (BinaryTreeNode<T> *u), BinaryTreeNode<T> *t);
46. void InOrder(void(*Visit)
47. (BinaryTreeNode<T> *u), BinaryTreeNode<T> *t);
48. void PostOrder(void(*Visit)
49. (BinaryTreeNode<T> *u), BinaryTreeNode<T> *t);
50. static void Free(BinaryTreeNode<T> *t) {delete t;}
51. static void Output(BinaryTreeNode<T> *t)
52. {cout << t->data << ' ';}
53. static void Add1(BinaryTreeNode<T> *t) {_count++;}
54. int Height(BinaryTreeNode<T> *t) const;
55. };

1.
2. template<class T>
3. bool BinaryTree<T>::Root(T& x) const
4. {// Return root data in x. // Return false if no root.
5. if (root) {x = root->data;
6. return true;}
7. else return false; // no root
8. }

1. template<class T>
2. void BinaryTree<T>::MakeTree(const T& element,
3. BinaryTree<T>& left, BinaryTree<T>& right)
4. {// Combine left, right, and element to make new tree.
5. // left, right, and this must be different trees.
6. // create combined tree
7. root = new BinaryTreeNode<T> (element, left.root, right.root);
8. // deny access from trees left and right
9. left.root = right.root = 0;
10. }

1. template<class T>
2. void BinaryTree<T>::BreakTree(T& element,
3. BinaryTree<T>& left, BinaryTree<T>& right)
4. {// left, right, and this must be different trees.

Bab 11 Pohon halaman 161


5. // check if empty
6. // break the tree
7. element = root->data;
8. left.root = root->LeftChild;
9. right.root = root->RightChild;
10.
11. delete root;
12. root = 0;
13. }

1. template<class T>
2. void BinaryTree<T>::PreOrder(void(*Visit)(BinaryTreeNode<T> *u),
3. BinaryTreeNode<T> *t)
4. {// Preorder traversal.
5. if (t) {Visit(t);
6. PreOrder(Visit, t->LeftChild);
7. PreOrder(Visit, t->RightChild);
8. }
9. }

1. template <class T>


2. void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T> *u),
3. BinaryTreeNode<T> *t)
4. {// Inorder traversal.
5. if (t) {InOrder(Visit, t->LeftChild);
6. Visit(t);
7. InOrder(Visit, t->RightChild);
8. }
9. }

1. template <class T>


2. void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T> *u),
3. BinaryTreeNode<T> *t)
4. {// Postorder traversal.
5. if (t) {PostOrder(Visit, t->LeftChild);
6. PostOrder(Visit, t->RightChild);
7. Visit(t);
8. }
9. }

Bab 11 Pohon halaman 162


1. template <class T>
2. int BinaryTree<T>::Height(BinaryTreeNode<T> *t) const
3. {// Return height of tree *t.
4. if (!t) return 0; // empty tree
5. int hl = Height(t->LeftChild); // height of left
6. int hr = Height(t->RightChild); // height of right
7. if (hl > hr) return ++hl;
8. else return ++hr;
9. }

// test binary tree class

1. #include <iostream.h>
2. #include "binary.h"
3.
4. // globals
5. int count = 0;
6. BinaryTree<int> a,x,y,z;
7.
8. template<class T>
9. void ct(BinaryTreeNode<T> *t) {count++;}
10.
11. void main(void)
12. {
13. y.MakeTree(1,a,a);
14. z.MakeTree(2,a,a);
15. x.MakeTree(3,y,z);
16. y.MakeTree(4,x,a);
17. cout << "Preorder sequence is ";
18. y.PreOutput();
19. cout << "Inorder sequence is ";
20. y.InOutput();
21. cout << "Postorder sequence is ";
22. y.PostOutput();
23. cout << "Level order sequence is ";
24. y.LevelOutput();
25. cout << "Number of nodes = ";
26. cout << y.Size() << endl;
27. cout << "Height = ";

Bab 11 Pohon halaman 163


28. cout << y.Height() << endl;
29. y.PreOrder(ct);
30. cout << "Count of nodes is " << count << endl;
31. }

Latihan
Konstruksikan rumus atau formula di bawah menjadi pohon. Mulailah dari
operator yang paling tinggi presedensinya menjadi akar kemudian operator lain
mengikuti di sebelah kiri atau kanan sesuai dengan urutan pengerjaannya. Setiap
operator akan menjadi node dalam, sedangkan semua operan akan menjadi node luar
(daun). Sebagai contoh :
(a + b) / c

akan menjadi pohon berikut :


Contoh :
/

+ C

A B

1. A/(B – C*D)

2. (-B + C)*D/(E - F)

3. E2 + (A – B)*(C + D/F)

4. (B2 – 4*A*C)/(2*A)

Lalu lakukan penelusuran dengan cara :


 preorder
 postorder
 level order

Bab 11 Pohon halaman 164


SKENARIO PERKULIAHAN MINGGU 12

Persiapan [50 menit]


01. Mahasiswa mengerjakan Pretest Praktikum
02. Mahasiswa mempelajari Struktur Data Pohon Setimbang (AVL)
03. Mahasiswa mencari contoh program Struktur Data Pohon Setimbang (AVL)
04. Catatan :
a. Boleh belajar bersama kelompok masing-masing
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]


00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing
01. Dosen membuka perkuliahan
02. Dosen menjelaskan definisi dan konstruksi Struktur Data Pohon Setimbang (AVL)
03. Dosen memberikan contoh Struktur Data Pohon Setimbang (AVL)
04. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
05. Dosen menjelaskan pembuatan Struktur Data Pohon Setimbang (AVL)
06. Mahasiswa mengikuti dengan compilernya masing-masing
07. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok memilih
tugasnya masing-masing

Kegiatan Diskusi [20 menit]


01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya masing-
masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]


01. Dosen memberikan rangkuman materi kuliah minggu ini
02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 12 Pohon Setimbang halaman 165


Bab XII
Pohon Setimbang
Tujuan pembelajaran:
Mahasiswa mampu menerapkan pembentukan pohon setimbang beserta operasi-
operasinya

A. Pendahuluan
Pohon setimbang (AVL Tree) adalah Binary searh Tree yang selisih tinggi antara cabang
kiri dan cabang kanan maksimum adalah 1. Operasi Penyisipan node baru dalam AVL Tree
adalah :
1. isi node baru akan ditelusuri dari root, bila lebih kecil akan mengikuti cabang kiri,
bila lebih besar, akan mengikut cabang kanan, sampai node baru tersebut menjadi
daun.
2. Untuk menjamin kondisi balance pada AVL tree, setelah penambahan sebuah node.
jalur dari node baru tersebut hingga root disimpan dan diperiksa kondisi balance pada
tiap node-nya.
3. Jika setelah penambahan, kondisi balance tidak terpenuhi pada node tertentu, maka
lakukan salah satu rotasi berikut:
a. Single rotation
b. Double rotation
Contoh :
 penambahan 3 pada AVL tree
B. Implementasi konsep pohon setimbang di dalam pemrogaman
Tiap node AVL dikonstruksikan menggunakan struktur AVLNode berikut :
Program 9.1
1. struct AVLNode {
2. int data ;
3. int balfact ;
4. AVLNode *left ;
5. AVLNode *right ;
6. };

Pohon AVL dikontruksikan mulai dari root. Data root beserta operasi yang diberlakukan pada
pohon AVL menggunakan class avltree di bawah ini :

Program 9.2
1. class avltree {

Bab 12 Pohon Setimbang halaman 166


2. private :
3. AVLNode *root ;
4. public :
5. avltree( ) ;
6. AVLNode* insert ( int data, int *h ) ;
7. static AVLNode* buildtree ( AVLNode *root, int data, int *h ) ;
8. void display( AVLNode *root ) ;
9. AVLNode* deldata ( AVLNode* root, int data, int *h ) ;
10. static AVLNode* del ( AVLNode *node, AVLNode* root, int *h ) ;
11. static AVLNode* balright ( AVLNode *root, int *h ) ;
12. static AVLNode* balleft ( AVLNode* root, int *h ) ;
13. void setroot ( AVLNode *avl ) ;
14. ~avltree( ) ;
15. static void deltree ( AVLNode *root ) ;
16. };

Implementasi selengkapnya dari operasi penyisipan node baru adalah sebagai berikut.

Program 9.3
1. AVLNode* avltree :: insert ( int data, int *h ) {
2. root = buildtree ( root, data, h ) ;
3. return root ;
4. }
5.
6. AVLNode* avltree :: buildtree ( AVLNode *root, int data, int *h ) {
7. AVLNode *node1, *node2 ;
8. if ( root == NULL ) {
9. root = new AVLNode ;
root -> data = data ;
10. root -> left = NULL ;
11. root -> right = NULL ;
12. root -> balfact = 0 ;
13. *h = TRUE ;
14. return ( root ) ;
15. }
16. if ( data < root -> data ) {
17. root -> left = buildtree ( root -> left, data, h ) ;
18. // If left subtree is higher
19. if ( *h ) {
20. switch ( root -> balfact ) {
21. case 1 :
22. node1 = root -> left ;
23. if ( node1 -> balfact == 1 ) {
24. cout << "\nRight rotation." ;
25. root -> left = node1 -> right ;
26. node1 -> right = root ;
27. root -> balfact = 0 ;
28. root = node1 ;
29. }
Bab 12 Pohon Setimbang halaman 167
30. else {
31. cout << "\nDouble rotation, left then right." ;
32. node2 = node1 -> right ;
33. node1 -> right = node2 -> left ;
34. node2 -> left = node1 ;
35. root -> left = node2 -> right ;
36. node2 -> right = root ;
37. if ( node2 -> balfact == 1 )
38. root -> balfact = -1 ;
39. else
40. root -> balfact = 0 ;
41. if ( node2 -> balfact == -1 )
42. node1 -> balfact = 1 ;
43. else
44. node1 -> balfact = 0 ;
45. root = node2 ;
46. }
47. root -> balfact = 0 ;
48. *h = FALSE ;
49. break ;
50. case 0 :
51. root -> balfact = 1 ;
52. break ;
53. case -1 :
54. root -> balfact = 0 ;
55. *h = FALSE ;
56. }
57. }
58. }
59. if ( data > root -> data ) {
60. root -> right = buildtree ( root -> right, data, h ) ;
61. if ( *h ) {
62. switch ( root -> balfact ) {
63. case 1 :
64. root -> balfact = 0 ;
65. *h = FALSE ;
66. break ;
67. case 0 :
68. root -> balfact = -1 ;
69. break ;
70. case -1 :
71. node1 = root -> right ;
72. if ( node1 -> balfact == -1 ) {
73. cout << "\nLeft rotation." ;
74. root -> right = node1 -> left ;
75. node1 -> left = root ;
76. root -> balfact = 0 ;
77. root = node1 ;
78. }

Bab 12 Pohon Setimbang halaman 168


79. else {
80. cout << "\nDouble rotation, right then left." ;
81. node2 = node1 -> left ;
82. node1 -> left = node2 -> right ;
83. node2 -> right = node1 ;
84. root -> right = node2 -> left ;
85. node2 -> left = root ;
86. if ( node2 -> balfact == -1 )
87. root -> balfact = 1 ;
88. else
89. root -> balfact = 0 ;
90. if ( node2 -> balfact == 1 )
91. node1 -> balfact = -1 ;
92. else
93. node1 -> balfact = 0 ;
94. root = node2 ;
95. }
96. root -> balfact = 0 ;
97. *h = FALSE ;
98. }
99. }
100. }
101. return ( root ) ;
102. }

Operasi penghapusan node :

Program 9.4
1. AVLNode* avltree :: deldata ( AVLNode *root, int data, int *h ) {
2. AVLNode *node ;
3. if ( root -> data == 13 )
4. cout << root -> data ;
5. if ( root == NULL ) {
6. cout << "\nNo such data." ;
7. return ( root ) ;
8. }
9. else {
10. if ( data < root -> data ) {
11. root -> left = deldata ( root -> left, data, h ) ;
12. if ( *h )
13. root = balright ( root, h ) ;
14. }
15. else {
16. if ( data > root -> data ) {
17. root -> right = deldata ( root -> right, data, h ) ;
18. if ( *h )
19. root = balleft ( root, h ) ;
20. }
21. else {
22. node = root ;
Bab 12 Pohon Setimbang halaman 169
23. if ( node -> right == NULL ) {
24. root = node -> left ;
25. *h = TRUE ;
26. delete ( node ) ;
27. }
28. else {
29. if ( node -> left == NULL ) {
30. root = node -> right ;
31. *h = TRUE ;
32. delete ( node ) ;
33. }
34. else {
35. node -> right = del ( node -> right, node, h ) ;
36. if ( *h )
37. root = balleft ( root, h ) ;
38. }
39. }
40. }
41. }
42. }
43. return ( root ) ;
44. }
45.
46. AVLNode* avltree :: del ( AVLNode *succ, AVLNode *node, int *h ) {
47. AVLNode *temp = succ ;
48. if ( succ -> left != NULL ) {
49. succ -> left = del ( succ -> left, node, h ) ;
50. if ( *h )
51. succ = balright ( succ, h ) ;
52. }
53. else {
54. temp = succ ;
55. node -> data = succ -> data ;
56. succ = succ -> right ;
57. delete ( temp ) ;
58. *h = TRUE ;
59. }
60. return ( succ ) ;
61. }

Di bawah ini adalah main function dengan skenario pembuatan pohon sebagai berikut :
Insert 20
Insert 6
Insert 29
Kemudian dilakukan operasi penghapusan :
Delete 20

Bab 12 Pohon Setimbang halaman 170


File btnode.h
1. int main( ){
2. avltree at ;
3. AVLNode *avl = NULL ;
4. int h ;
5. cout << "Insert 20\n";
6. avl = at.insert ( 20, &h ) ;
7. at.setroot ( avl ) ;
8. at.display ( avl ) ;
9. system("PAUSE");
10. cout << "Insert 6\n";
11. avl = at.insert ( 6, &h ) ;
12. at.setroot ( avl ) ;
13. at.display ( avl ) ;
14. system("PAUSE");
15. cout << "Insert 29\n";
16. avl = at.insert ( 29, &h ) ;
17. at.setroot ( avl ) ;
18. at.display ( avl ) ;
19. system("PAUSE");
20. cout << "Insert 5\n";
21. avl = at.insert ( 5, &h ) ;
22. at.setroot ( avl ) ;
23. at.display ( avl ) ;
24. system("PAUSE");
25. cout << "Delete 20\n";
26. avl = at.deldata ( avl, 20, &h ) ;
27. at.setroot ( avl ) ;
28. cout << endl << "AVL tree after deletion of a node 20 :\n" ;
29. at.display ( avl ) ;
30. system("PAUSE");
31. return EXIT_SUCCESS;
32. }

tugas
1. Diberikan data 4, 16, 55, 17, 33, 21, 48, 15. Gambarkanlah pohon AVL nya.
2. Kemudian ketika data 15 dan 55 di delete, pohon AVL tersebut menjadi seperti apa?
Gambarkan!
3. Diberikan data 49, 26, 5, 17, 53, 12, 42, 31. Gambarkanlah pohon AVL nya.
4. Kemudian ketika data 12 dan 49 di delete, pohon AVL tersebut menjadi seperti apa?
Gambarkan!
5. Ubahlah main function di atas dengan skenario berikut ini :

Bab 12 Pohon Setimbang halaman 171


Insert 20
Insert 6
Insert 29
Insert 5
Insert 12
Insert 25
Insert 32
Insert 10
Insert 15
Insert 27
Insert 13
Delete 20
Delete 12
Insert 2
Insert 28
Insert 20
Insert 8
Delete 15
Delete 6
Delete 5
Delete 13
Delete 10
Insert 22
Insert 23

Bab 12 Pohon Setimbang halaman 172


SKENARIO PERKULIAHAN MINGGU 13

Persiapan [50 menit]


01. Mahasiswa mengerjakan Pretest Praktikum
02. Mahasiswa mempelajari Struktur Data Pohon Huffman
03. Mahasiswa mencari contoh program Struktur Data Pohon Huffman
04. Catatan :
a. Boleh belajar bersama kelompok masing-masing
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat

Kegiatan Kuliah [60 menit]


00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing
01. Dosen membuka perkuliahan
02. Dosen menjelaskan definisi dan konstruksi Struktur Data Pohon Huffman
03. Dosen memberikan contoh Struktur Data Pohon Huffman
04. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
05. Dosen menjelaskan pembuatan Struktur Data Pohon Huffman
06. Mahasiswa mengikuti dengan compilernya masing-masing
07. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok memilih
tugasnya masing-masing

Kegiatan Diskusi [20 menit]


01. Mahasiswa diberikan kesempatan mendiskusikan tugas dengan kelompoknya masing-
masing
02. Boleh berbagi tugas analisis, coding, dan presentasi. Analisis di kertas, coding di
compiler, persiapan presentasi
03. Semua hasil diskusi disimpan dalam Google Drive kelompok
04. Menginvite email ketua kelompok dari kelompok lain

Penutup [20 menit]


01. Dosen memberikan rangkuman materi kuliah minggu ini
02. Dosen memberikan pengumuman uji kompetensi minggu depan
03. Mahasiswa diberikan kesempatan untuk bertanya
04. Dosen menutup perkuliahan

Bab 13 Pohon Huffman halaman 173


Bab XIII
Pohon Huffman
Tujuan pembelajaran:
1. Mahasiswa mampu mengkonstruksikan pohon Huffman
2. Mahasiswa mampu menghitung efisiensi pohon huffman

A. Pendahuluan
Metode kode Huffman adalah suatu teknik kompresi data secara statistik yang bekerja
dengan mereduksi panjang kode rata-rata dan menghasilkan kode prefiks yang digunakan untuk
merepresentasikan simbol-simbol dari suatu jenis huruf. Diusulkan oleh Dr. David A. Huffman
pada tahun 1952. Huffman coding menggunakan struktur pohon dalam pemrosesannya. Pohon
yang dibuat dinamakan pohon Huffman. Pohon Huffman diimplementasikan menggunakan
pohon biner.
Algoritma Huffman :
1. Menghitung banyaknya jenis karakter dan jumlah dari masing-masing karakter yang
terdapat dalam sebuah file.
2. Menyusun setiap jenis karakter dengan urutan jenis karakter yang jumlahnya paling
sedikit ke yang jumlahnya paling banyak.
3. Membuat pohon biner berdasarkan urutan karakter dari yang jumlahnya terkecil ke
yang terbesar, dan memberi kode untuk tiap karakter.
4. Mengganti data yang ada dengan kode bit berdasarkan pohon biner.
5. Menyimpan jumlah bit untuk kode bit yang terbesar, jenis karakter yang diurutkan dari
frekuensi keluarnya terbesar ke terkecil beserta data yang sudah berubah menjadi
kode bit sebagai data hasil kompresi.
Contoh :
String : “AAAABBBCCCCCD”

1. Mencatat karakter yang ada dan jumlah tiap karakter.


A = 4, B = 3, C = 12, D=1
2. Mengurutkan karakter dari yang jumlahnya paling sedikit ke yang paling banyak yaitu :
D, B, A, C
3. Membuat pohon biner berdasarkan urutan karakter yang memiliki frekuensi
terkecil hingga yang paling besar.

Bab 13 Pohon Huffman halaman 174


0 1

0 1

0 1

D B A C

4. Mengganti data yang ada dengan kode bit berdasarkan pohon biner yang dibuat.
Penggantian karakter menjadi kode biner, dilihat dari node yang paling atas atau
disebut node akar :
A = 01, B = 001, C = 1, D = 000.
5. Selanjutnya berdasarkan pada kode biner masing-masing karakter ini, semua
karakter dalam file dapat diganti menjadi :
01010101001001001111110001111111
Karena angka 0 dan angka 1 mewakili 1 bit, sehingga data bit di atas terdiri dari 32 bit
atau 4 byte (1 byte = 8 bit). Menyimpan kode bit dari karakter yang frekuensinya
terbesar, jenis karakter yang terdapat di dalam file dan data file teks yang sudah
dikodekan. Cara menyimpan data jenis karakter adalah dengan mengurutkan data
jenis karakter dari yang frekuensinya paling banyak sampai ke yang paling sedikit,
menjadi : [C,A,B,D]
B. Penerapan pohon huffman dalam pemrogaman
Perhatikan progam untuk mengkonstruksikan pohon huffman di bawah ini:
Program 10.1
1. template<class T> class Queue {
2. public:
3. Queue(int d=2);
4. ~Queue(void);
5. void enq(T*);
6. T* deq(void);
7. T* front(void);
8. bool empty(void) const;
9. bool full(void) const;
private:
10. int elemenAkhir;
11. T* *arr;
12. int size;

Bab 13 Pohon Huffman halaman 175


13. static const int SIZE=10;
14. int D;
15. Queue(const Queue &);
16. const Queue & operator=(const Queue &);
17. void reheapup(int, int);
18. void reheapdown(int, int);
19. void swap(T* &, T* &);
20. };
Untuk mengkonstruksikan pohon Huffman, kita buat class Tree berikut :
Program 10.2
1. class Tree {
2. private:
3. class Node {
4. public:
5. unsigned int freq;
6. unsigned char ch;
7. Node *left, *right;
8. Node(void) :freq(0), ch('\0'), left(NULL), right(NULL) {}
9. };
Node *root;
10. Tree(const Tree &);
11. const Tree & operator=(const Tree &);
12. void chop(Node * N);
13. void print(ostream &, Node *, int) const;
14. void print(Node *, int) const;
15. public:
16. Tree(void);
17. ~Tree(void);
18. friend ostream & operator<<(ostream &, const Tree &);
19. unsigned int get_freq(void) const;
20. unsigned char get_char(void) const;
21. void set_freq(unsigned int);
22. void set_char(unsigned char);
23. Node* get_left(void) const;
24. Node* get_right(void) const;
25. void set_left(Node *);
26. void set_right(Node *);
27. Node* get_root(void) const;
28. bool operator==(const Tree &) const;
29. bool operator!=(const Tree &) const;
30. bool operator<(const Tree &) const;
31. bool operator>(const Tree &) const;
32. bool operator<=(const Tree &) const;
33. bool operator>=(const Tree &) const;
34. void huf(Node *, unsigned char, string, string &) const;
35. void huf_list(Node *, string) const;
36. bool get_huf_char(string, unsigned char &) const;
37. string print_char(Node *) const;
38. };

Bab 13 Pohon Huffman halaman 176


Main function dari pohon Huffman adalah sebagai berikut :

Program 10.3
1. int main( int argc, char * argv[] ) {
2. string in_name;
3. string out_name;
4. bool encode = true;
5. bool verbose = false;
6. for ( int i = 1 ; i < argc ; ++i ) {
7. if ( !strcmp( "-h", argv[i] ) || !strcmp( "--help", argv[i] ) ) {
8. usage_msg( argv[0] );
9. exit( HELP_ERROR );
10. }
11. else if ( !strcmp( "-i", argv[i] ) ) {
12. cerr << "File input : '" << argv[++i] << "'" << endl;
13. in_name = argv[i];
14. }
15. else if ( !strcmp( "-o", argv[i] ) ) {
16. cerr << "File output: '" << argv[++i] << "'" << endl;
17. out_name = argv[i];
18. }
19. else if ( !strcmp( "-d", argv[i] ) ) {
20. encode = false;
21. }
22. else if ( !strcmp( "-e", argv[i] ) ) {
23. encode = true;
24. }
25. else if ( !strcmp( "-v", argv[i] ) ) {
26. verbose = true;
27. }
28. }
29. if ( !in_name.size() || !out_name.size() ) {
30. cerr << "file input dan output HARUS ADA!" << endl;
31. usage_msg( argv[0] );
32. exit( HELP_ERROR );
33. }
34. if ( encode ) {
35. cerr << "running in encoder mode" << endl;
36. encoder( in_name, out_name, verbose );
37. }
38. else {
39. cerr << "running in decoder mode" << endl;
40. decoder( in_name, out_name, verbose );
41. }
42. cerr << "Selesai .... " << endl;
43. return 0;
44. }

Bab 13 Pohon Huffman halaman 177


Tugas
1.Carilah sebuah lagu dengan menggunakan Google Search. Setelah itu, menggunakan algoritma
Huffman, buatlah Huffman Code beserta pohon Huffmannya.
2.Dengan menggunakan source Code pohon Huffman di atas, gunakan file lagu saat pretes.
Amati berapa besar prosentase hasil enkodernya. Cocokkan dengan analisis pretes.

Bab 13 Pohon Huffman halaman 178


SKENARIO PERKULIAHAN MINGGU 14

Kegiatan Kuliah [30 menit]


00. Sebelum kuliah dimulai mahasiswa mengumpulkan Pretest ke asisten masing-masing
01. Dosen membuka perkuliahan
02. Dosen menjelaskan Object Orientated Programming
03. Dosen memberikan contoh Object Orientated Programming
04. Mahasiswa mengikuti dengan compilernya masing-masing, diutamakan dengan
menggunakan hape yang online
05. Dosen menjelaskan pembuatan Object Orientated Programming
06. Mahasiswa mengikuti dengan compilernya masing-masing
07. Dosen memberikan tugas untuk didiskusikan oleh kelompok. Setiap kelompok memilih
tugasnya masing-masing

Presentasi Tugas Proyek [70 menit]


01. Mahasiswa mempresentasikan Tugas Proyek
02. Setiap kelompok diberikan kesempatan presentasi 10 menit

Bab 14 Mengenal OOP Melalui UML Class Diagram halaman 179


Bab XIV
Mengenal OOP Melalui UML Class Diagram
Tujuan Pembelajaran:
1. Mahasiswa mampu menggunakan UML
2. Mahasiswa mengenali komponen dalam class
A. Pendahuluan
Diagram kelas dalam Unified Modeling Language (UML) adalah jenis diagram struktur
statis yang menggambarkan struktur dari suatu sistem dengan menunjukkan kelas sistem, atribut
mereka, operasi (atau metode), dan hubungan antar kelas.
Bila referensi kita adalah sebuah class dalam C++, maka atribut dikenal dengan bagian
private data member. Operasi yang ada dalam class C++ dikenal dengan bagian member function,
biasanya bersifat public sehingga dapat diakses oleh objek di luar kelas.
Dalam UML class diagram, class digambarkan sebagai kotak yang berisi 3 bagian, yaitu :
Bagian atas : nama kelas
Bagian tengah : berisi atribut
Bagian bawah : berisi operasi/ metode
B. Implementasi Class Diagram menggunakan RAPTOR

Kita gunakan class Convert yang akan menjadi mesin konversi dari m menjadi cm dan inch. Untuk
itu kita perlu :
Atribut :
Input : m
Output : cm, inch
Sintaks setiap Method berikut :
SetM : menerima parameter input meters dari luar class sebagai inisialisasi harga atribut m
public void SetM(double meters)
mTOcm : mengkonversi m ke cm
public void mTOcm()
mTOinch : mengkonversi m ke inch
public void mTOinch()
Bab 14 Mengenal OOP Melalui UML Class Diagram halaman 180
print : mencetak hasil konversi
public void print()
Semua tipe data menggunakan double karena terdapat operator /. Hasil dari definisi di atas menjadi
:

Bentuk UML menjadi :

Bab 14 Mengenal OOP Melalui UML Class Diagram halaman 181


Kita menggunakan object this tiap kali menggunakan member dari class Convert. Method SetM
dalam RAPTOR menjadi :

Method mTOcm adalah :

Method mTOInch adalah :

Untuk menampilkan hasil konversi, menggunakan method print berikut :

Bab 14 Mengenal OOP Melalui UML Class Diagram halaman 182


Perhatikan : setiap kali kita mengakses member (khususnya data member) kita menggunakan this
object. Sekarang kita menyusun skenario untuk membuat main function :
1. Buat object conversion dari class Convert
2. Input m dari luar class
3. m masuk dan jalankan method SetM untuk menginisialisasi data member m lewat parameter
meters
4. jalankan method mTOcm untuk mengkonversi m ke cm
5. jalankan method mTOinch untuk mengkonversi m ke inch
6. cetak hasil konversi

Fungsi main dalam RAPTOR menjadi :

Bab 14 Mengenal OOP Melalui UML Class Diagram halaman 183


Bab 14 Mengenal OOP Melalui UML Class Diagram halaman 184
FM-UAD-PBM-04-16/R1

SOAL UJIAN TENGAH SEMESTER GASAL TA 2016/2017


FAKULTAS TEKNOLOGI INDUSTRI
MATA KULIAH : Struktur Data (3 sks) PRODI : Teknik Informatika
Drs. Wahyu Pujiyono, M.Kom
DOSEN : KELAS/SEM : A, B, C / III

HARI/TANGGAL : Selasa, 27 Oktober 2015 RUANG : Aud, 312, 313

WAKTU : 10.00 WIB / 90 Menit SIFAT UJIAN : Closed Books

PETUNJUK :

1. Berdoalah sebelum mengerjakan soal dan nyatakan dalam hati anda bahwa
“Saya mengerjakan ujian ini dengan jujur”.
2. Kerjakan dengan lengkap dari soal yang paling mudah
3. Soal BOLEH DIBAWA PULANG

[Pushdown Stack – Nilai 20]

Diberikan ekspresi dalam notasi postfix berikut :

598–71-*+7*

a. Gambarkan operasi push dan pop dalam pushdown stack dari notasi postfix di atas [10]

b. Tulislah notasi infiksnya [5]

c. Berapa nilai akhir dari ekspresi tersebut ? [5]

[Tipe Data Abstrak – Nilai 30]

Diberikan pasangan data (x, y) di mana x berupa integer dan y berupa karakter. Tidak
diperbolehkan adanya duplikasi data integer. Operasi-operasi yang diperlakukan pada data di
antaranya : pembuatan objek baru, memasukkan data lewat keyboard, penjumlahan sepasang
data (2 buah objek) dan mencetak pasangan data (objek)

a. [nilai 10] buatlah konstruksi tipe data abstrak dengan nama PASANGAN
b. [nilai 5] buatlah class berkaitan dengan tipe data abstrak yang telah dibuat
c. [nilai 15] buatlah operator overloading “+” untuk menjumlah sepasang data (2 buah
objek)

[Rekursi dan Array – Nilai 20]

Diberikan procedure iteratif untuk mencetak setiap elemen dari array berikut:

void cetak (char *s) {


for (int i=0; i<strlen(s); i++)
cout << s[i] << “ “ ;
}

a. [nilai 10] Buatlah procedure rekursif dalam C++


b. [nilai 10] Buatlah procedure, pilih salah satu : iteratif atau rekursif, untuk mencetak
elemen array secara terbalik

[Pointer dan Link List - 30]

halaman 185
FM-UAD-PBM-04-16/R1

1. Berikut ini adalah struktur data dan gambar operasi dari link list. Dalam tiap gambar,
berilah code program dalam C++. Diberikan struktur data untuk node adalah :
class Titik {
private :
char info;
Node *berikutnya;
};

awa
l enull

a b f c d

Dengan mengikuti struktur data Node yang diberikan, berikan code dalam C++ untuk
menambah node dengan info “f” (sudah disediakan) di antara “c” dan “d”. Posisi pointer
awal, baru dan p sudah ada pada posisi sebagaimana dalam gambar di atas.
Tulis Jawaban dengan format berikut :
[Nilai 10] Langkah no 1 kodenya :

__________________________________________________

[Nilai 10] Langkah no 2 kodenya :


__________________________________________________

[Nilai 10] Menggunakan gambar yang sama, tulislah kode untuk menghapus elemen ‘e’

__________________________________________________

Diverifikasi oleh : Disusun oleh :


Ketua Program Studi Penanggungjawab Keilmuan Dosen Pengampu

Sri Winiarti, ST., M.Cs. Drs. Wahyu Pujiyono, M.Kom.

halaman 186
FM-UAD-PBM-04-16/R1

SOAL UJIAN AKHIR SEMESTER GASAL TA 2016/2017


FAKULTAS TEKNOLOGI INDUSTRI
MATA KULIAH : Struktur Data PRODI : Teknik Informatika
Drs. Wahyu Pujiyono, M.Kom
DOSEN : KELAS/SEM : A, B, C / III

HARI/TANGGAL : SENIN, 9 Januari 2017 RUANG : 306, 307

WAKTU : 08.00-10.00 WIB / 120 Menit SIFAT UJIAN : Closed Books

PETUNJUK :

4. Berdoalah sebelum mengerjakan soal dan nyatakan dalam hati anda bahwa
“Saya mengerjakan ujian ini dengan jujur”.
5. Kerjakan dengan lengkap dari soal yang paling mudah

[Struktur Data – Nilai 30]

Struktur data antrian memiliki 2 operasi dasar, yaitu memasukkan data ke antrian (enqueue) dan
mengeluarkan data dari antrian (dequeue). Sifatnya, data yang masuk lebih dulu akan keluar dulu
(first come first serve). Perbedaan antrian dengan antrian berprioritas adalah pada operasi
memasukkan data dalam antrian (enqueue), di mana data yang masuk akan berada pada urutan
prioritasnya. Asumsikan, data berupa integer, nilai integer kecil berarti prioritas lebih tinggi dibanding
integer besar.

[Nilai 10]

Konstruksikan struktur data yang digunakan.

a. untuk mahasiswa nomor gasal, menggunakan array

b. untuk mahasiswa nomor genap, menggunakan link list

[Nilai 20]

Implementasikan operasi priority enqueue menggunakan bahasa pemrograman C++.

[Pohon Ekspresi – Nilai 35]

Diberikan ekspresi dalam notasi postfiks berikut ini :

258–*24/72–3**+
a. konstruksikan pohon ekspresi dari notasi postfiks di atas [Nilai 10]

b. tulislah urutan penelusuran : preorder dan inorder [Nilai 20]

c. berapakah nilai ekspresi di atas setelah dievaluasi? [Nilai 5]

[Pohon Setimbang – Nilai 35]

Diberikan pohon setimbang dalam kondisi sebagai berikut:

halaman 187
FM-UAD-PBM-04-16/R1

Berikan gambar perubahan pohon setelah operasi berikut ini secara berturut-turut :
a. hapus 91 [nilai 20]
b. setelah langkah a, tambah data 79 [nilai 15]

Perhatikan, gambar harus lengkap dengan :


1. flag tiap node pada setiap tahap perubahan
2. tahap perubahan langkah demi langkah (bukan hanya hasil akhir) beserta dengan
panah yang menunjukkan arah putaran
Bila tidak dilengkap dengan poin 1 dan 2 ini, jawaban tidak dinilai.

Diverifikasi oleh : Disusun oleh :


Ketua Program Studi Penanggungjawab Keilmuan Dosen Pengampu

Sri Winiarti, ST., M.Cs. Drs. Wahyu Pujiyono, M.Kom.

halaman 188
FM-UAD-PBM-04-16/R1

SOAL TENGAH SEMESTER GASAL TA 2017/2018


FAKULTAS TEKNOLOGI INDUSTRI
MATA KULIAH : Struktur Data PRODI : Teknik Informatika
Drs. Wahyu Pujiyono, M.Kom
DOSEN : KELAS/SEM : A, B, C / III

HARI/TANGGAL : Senin, 23 Oktober 2017 RUANG : Aud, 315


Closed Books,
bawa catatan
WAKTU : 08.00 – 09.30 WIB / 90 Menit SIFAT UJIAN : tulisan tangan
warna BIRU asli
maksimal 1 lembar

PETUNJUK :

6. Berdoalah sebelum mengerjakan soal dan nyatakan dalam hati anda bahwa
“Saya mengerjakan ujian ini dengan jujur”.
7. Kerjakan dengan lengkap dari soal yang paling mudah

[Pushdown Stack – Nilai 20]

Diberikan ekspresi dalam notasi postfix berikut :

598–71-*+7*

d. [Nilai 10] Gambarkan operasi push dan pop dalam pushdown stack dari notasi postfix di atas

e. [Nilai 5] Tulislah notasi infiksnya

f. [Nilai 5] Berapa nilai akhir dari ekspresi tersebut ?

[Representasi Data dan Pengelolaan Array – Nilai 30]

Diketahui array A bertipe int, maksimum banyaknya data array A adalah 5. Array A berisi data :

8 3 4 7 2

a. [Nilai 5] Buatlah deklarasi dan inisialisasi array A dengan data di atas

b. [Nilai 10] Buat function tukar(a,b), untuk menukar nilai variabel a menjadi b demikian pula
sebaliknya.

c. [Nilai 10] Buat function ganjil_depan, sehingga output dari function dengan data array A akan
menjadi :

3 7 8 4 2
Prinsipnya : bila ketemu data genap (saat ini) dan data di sebelah kanan ganjil, tukar datanya

d. [Nilai 5] Buat main function dari program tersebut

[Konstruksi Struktur data dan reperesentasi data link list – Nilai 30]

Perhatikan gambar berikut, beserta semua variabel yang ada.

a. [Nilai 10] buat struktur data menggunakan struct dengan nama Node

halaman 189
FM-UAD-PBM-04-16/R1

b. [Nilai 10] buat pointer P, dengan posisi pertama menunjuk Node A, lalu jalankan sampai
menunjuk Node B. Sisipkan Node X setelah Node B. Tak perlu dalam bentuk function.
Hanya langkah-langkahnya saja dalam C++.

c. [Nilai 10] Buat langkah-langkah dalam C++ untuk menghapus Node A

[Rekursi dan Array – Nilai 20]

Diberikan procedure iteratif untuk mencetak setiap elemen dari array A berikut:

void cetak(int A[], int n) {


for (int i=0; i<n; i++)
cout << A[i] << " ";
cout << "\n";
}

c. [nilai 10] Buatlah procedure rekursif dalam C++


d. [nilai 10] Buatlah procedure, pilih salah satu : iteratif atau rekursif, untuk mencetak
elemen array A secara terbalik

Diverifikasi oleh : Disusun oleh :


Ketua Program Studi Penanggungjawab Keilmuan Dosen Pengampu

Sri Winiarti, ST., M.Cs. Drs. Wahyu Pujiyono, M.Kom.

halaman 190
FM-UAD-PBM-04-16/R1

SOAL AKHIR SEMESTER GASAL TA 2017/2018


FAKULTAS TEKNOLOGI INDUSTRI
MATA KULIAH : Struktur Data PRODI : Teknik Informatika

DOSEN : Drs. Wahyu Pujiyono, M.Kom KELAS/SEM : A, B, C / III

HARI/TANGGAL : Senin, 8 Januari 2018 RUANG : 312, 313, 314

Buka laptop,
WAKTU : 08.00 – 10.00 WIB / 120 Menit SIFAT UJIAN :
closed booked

PETUNJUK :

8. Berdoalah sebelum mengerjakan soal dan nyatakan dalam hati anda bahwa
“Saya mengerjakan ujian ini dengan jujur”.
9. Kerjakan dengan lengkap dari soal yang paling mudah
10. Soal boleh dibawa pulang

[Pohon Setimbang – Nilai 20] Kerjakan 20 menit pertama di awal, boleh buka laptop
Diberikan sederatan input integer sebagai berikut : 10, 85, 15, 70, 20, 60

a. [Nilai 15] Setiap kali membaca data, langkah per langkah buatlah pohon setimbangnya
lengkap beserta flag yang menunjukkan selisih kedalaman cabang dari setiap node
dan arah panah yang menunjukkan pemutaran node. Bila saat memasukkan data pohon
TIDAK SETIMBANG, setimbangkan pohon tersebut sampai data habis.
b. [Nilai 5] Dari hasil akhir pohon yang telah SETIMBANG di atas, lalu lakukan penghapusan
node dengan data 15. Gambarkan pohon hasil penghapusannya.
Catatan penting : tanpa flag dan panah arah putaran node, jawaban tida memperoleh nilai

Setelah 20 menit pertama, tutup laptopnya dan mulai mengerjakan soal selanjutnya.

[Struktur Data Antrian – Nilai 25]

Antrian adalah sebuah struktur data dengan sifat First In First Out. Dengan menggunakan
representasi penyimpanan data link list :

a. [Nilai 10] sajikan struktur data antrian, dengan INFO bilangan (angka) dan pointer NEXT
menjadi struktur node link list
b. dari jawaban poin (a) di atas, buatlah gambaran operasi link list dari operasi yang berlaku
terhadap antrian (data masuk dan data keluar saja) dan implementasinya dalam bahasa C++
[Nilai 15

[Pohon Huffman – Nilai 25]

Diberikan deretan karakter beserta frekuensinya sebagai berikut :

Karakter A E I O U S R N D C T L H

Frekuensi 80 125 73 76 27 65 61 71 40 31 93 41 55

Jawablah pertanyaan berikut :

a. Dari tabel karakter beserta frekuensinya, konstruksikan pohon Huffmannya [Nilai 15]

halaman 191
FM-UAD-PBM-04-16/R1

b. Bila deretan karakter di atas dapat menggunakan HANYA 4 bit, hitunglah efisiensi dari
pohon Huffman (dalam prosentase) [Nilai 10]

[Konstruksi dan Penelusuran Pohon Biner – Nilai 30]

e. [Nilai 10] Konstruksikan pohon biner dari ekspresi infiks berikut :


–x – y * z + (a+b+c/d*e)
f. [Nilai 20] Kemudian telusurilah dengan preorder dan postorder.

Diverifikasi oleh : Disusun oleh :


Ketua Program Studi Penanggungjawab Keilmuan Dosen Pengampu

Sri Winiarti, ST., M.Cs. Drs. Wahyu Pujiyono, M.Kom.

halaman 192
FM-UAD-PBM-04-16/R1

SOAL TENGAH SEMESTER GASAL TA 2018/2019


FAKULTAS TEKNOLOGI INDUSTRI
MATA KULIAH : Struktur Data PRODI : Teknik Informatika
Drs. Wahyu Pujiyono, M.Kom
DOSEN : KELAS/SEM : A, B, C / III

HARI/TANGGAL : Senin, 29 Oktober 2018 RUANG : 312, 313, 314

WAKTU : 14.30 – 16.30 WIB / 90 Menit SIFAT UJIAN : Buku tertutup

PETUNJUK :

11. Berdoalah sebelum mengerjakan soal dan nyatakan dalam hati anda bahwa
“Saya mengerjakan ujian ini dengan jujur”.
12. Kerjakan dengan lengkap dari soal yang paling mudah

[Pushdown Stack – Nilai 20]

Diberikan ekspresi dalam notasi postfix berikut :

598–71-*+7*

g. [Nilai 10] Gambarkan operasi push dan pop dalam pushdown stack dari notasi postfix di atas

h. [Nilai 5] Tulislah notasi infiksnya

i. [Nilai 5] Berapa nilai akhir dari ekspresi tersebut ?

[Representasi Data dan Pengelolaan Array – Nilai 30]

Diketahui array A bertipe int, maksimum banyaknya data array A adalah 5. Array A berisi data :

8 3 4 7 2

e. [Nilai 5] Buatlah deklarasi dan inisialisasi array A dengan data di atas

f. [Nilai 10] Buat function tukar(a,b), untuk menukar nilai variabel a menjadi b demikian pula
sebaliknya.

g. [Nilai 10] Buat function ganjil_depan, sehingga output dari function dengan data array A akan
menjadi :

3 7 8 4 2
Prinsipnya : bila ketemu data genap (saat ini) dan data di sebelah kanan ganjil, tukar datanya

h. [Nilai 5] Buat main function dari program tersebut

[Konstruksi Struktur data dan reperesentasi data link list – Nilai 30]

Perhatikan gambar berikut, beserta semua variabel yang ada.

d. [Nilai 10] buat struktur data menggunakan struct dengan nama Node

e. [Nilai 10] buat pointer P, dengan posisi pertama menunjuk Node A, lalu jalankan sampai
menunjuk Node B. Sisipkan Node X setelah Node B. Tak perlu dalam bentuk function.
Hanya langkah-langkahnya saja dalam C++.
halaman 193
FM-UAD-PBM-04-16/R1

f. [Nilai 10] Buat langkah-langkah dalam C++ untuk menghapus Node A

[Rekursi dan Array – Nilai 20]

Diberikan procedure iteratif untuk mencetak setiap elemen dari array A berikut:

void cetak(int A[], int n) {


for (int i=0; i<n; i++)
cout << A[i] << " ";
cout << "\n";
}

g. [nilai 10] Buatlah procedure rekursif dalam C++


h. [nilai 10] Buatlah procedure, pilih salah satu : iteratif atau rekursif, untuk mencetak
elemen array A secara terbalik

Diverifikasi oleh : Disusun oleh :


Ketua Program Studi Penanggungjawab Keilmuan Dosen Pengampu

Sri Winiarti, ST., M.Cs. Drs. Wahyu Pujiyono, M.Kom.

halaman 194
FM-UAD-PBM-04-16/R1

SOAL AKHIR SEMESTER GASAL TA 2018/2019


FAKULTAS TEKNOLOGI INDUSTRI
MATA KULIAH : Struktur Data PRODI : Teknik Informatika

DOSEN : Drs. Wahyu Pujiyono, M.Kom KELAS/SEM : A, B, C / III

HARI/TANGGAL : Selasa, 8 Januari 2019 RUANG : 104, 105, 106

Buka catatan 1
WAKTU : 10.15 – 11.45 WIB / 120 Menit SIFAT UJIAN :
lembar asli

PETUNJUK :

13. Berdoalah sebelum mengerjakan soal dan nyatakan dalam hati anda bahwa
“Saya mengerjakan ujian ini dengan jujur”.
14. Kerjakan dengan lengkap dari soal yang paling mudah
15. Soal boleh dibawa pulang

[Pohon Setimbang – Nilai 30]

Diberikan sederatan input integer sebagai berikut : 10, 85, 15, 70, 20, 60

c. [Nilai 20] Setiap kali membaca data, langkah per langkah buatlah pohon setimbangnya
lengkap beserta flag yang menunjukkan selisih kedalaman cabang dari setiap
node dan arah panah yang menunjukkan pemutaran node. Bila saat memasukkan
data pohon TIDAK SETIMBANG, setimbangkan pohon tersebut sampai data habis.
d. [Nilai 10] Dari hasil akhir pohon yang telah SETIMBANG di atas, lalu lakukan
penghapusan node dengan data 15. Gambarkan pohon hasil penghapusannya.
Catatan penting : tanpa flag dan panah arah putaran node, jawaban tidak memperoleh nilai

[Struktur Data Tumpukan – Nilai 30]

Pertimbangkan tumpukan piring dengan ukuran:


 Piring A ukuran besar
 Piring B ukuran sedang
 Piring C ukuran kecil
Aturan yang berlaku:

1. piring besar tidak boleh berada di atas piring yang lebih kecil
2. bila ada piring yang sama besar, piring yang baru masuk ditempatkan di atas
3. piring yang baru masuk, disisipkan tempatnya sesuai dengan aturan nomor 1 dan 2

Dengan menggunakan representasi penyimpanan data link list :

c. [Nilai 10] Sajikan Struktur Data tumpukanpiring dengan besarpiring bertipe karakter
dan pointer berikut menjadi struktur node link list
d. dari jawaban poin (a) di atas, buatlah gambaran operasi link list dari operasi PUSH yang
berlaku terhadap tumpukan piring dengan aturan yang ditetapkan dan implementasinya
dalam bahasa C++ [Nilai 20]
Catatan : kata yang ditebalkan adalah variabel, jangan diganti!

[Konstruksi dan Penelusuran Pohon Biner – Nilai 40]

i. [Nilai 10] Konstruksikan pohon biner dari ekspresi infiks berikut :


9 * 2 + 1 - (5+4) / (3 - (8-6) * 7)

halaman 195
FM-UAD-PBM-04-16/R1

Berapa nilai (setelah dihitung) dari ekspresi di atas?

j. [Nilai 30] Kemudian telusurilah dengan pre-order, post-order dan level-order.

Diverifikasi oleh : Disusun oleh :


Ketua Program Studi Penanggungjawab Keilmuan Dosen Pengampu

Sri Winiarti, ST., M.Cs. Drs. Wahyu Pujiyono, M.Kom.

halaman 196
DAFTAR PUSTAKA

1. Aspnes, James, 2015, Data Structures and C Programming - Computer Science


Sen, Priya, 2016, Data Structures & Algorithms

2. Goodrich, Michael T., 2011, Data Structures and Algorithms in C++ 2e

3. James R., Stefan B., dan David W, 2003, A Laboratory Course in C++ Data
Structure, Jones and Barlett Pub, Subbury USA

4. Karumanchi, Narasimha, 2016, Data Structure and Algorithmic Thinking with Python Data
Structure and Algorithmic Puzzles, CareerMonk Publications

5. Ramesh, Anand, dan Gautam Vasappanavara, C & Data Structures by Practice, New
Age International, New Delhi, 2007

6. Sahni, 5, Data Structures, Algoritms and Application in C++, McGraww Hill Co,
Singapore, 2009

7. Weiss, Mark Allen, 2013, Data Structures and Algorithm Analysis in C++ - Manal Helal Site

8. http://frank.mtsu.edu/~csci217/manual

9. http://code.activerstate.com/recipes/577480-huffman-data-compression/

10. http://oopweb.com/Algorithms/Documents/AnimatedAlgorithms/VolumeFrame.html

11. http://www.cs.usfca.edu/~galles/visualization/

12. http://webdiis.unizar.es/asignaturas/EDA/AVLTree/avltree.html

13. https://visualgo.net/bn/bst

halaman 197
ISBN:

Anda mungkin juga menyukai