BUKU AJAR
MATA KULIAH
STRUKTUR DATA
NAMA PENERBIT
KATA PENGANTAR
Pemrograman C++
Tujuan Pembelajaran
A. Pendahuluan
Untuk menyelesaikan permasalahan dalam kehidupan real dengan bantuan
komputer diperlukan :
a. struktur data
b. algoritma
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; }
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
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. 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.
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;
y = new int (100);
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);
}
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!
n! = n * (n-1)!
yang ditulis sebagai
faktorial := n * faktorial(n-1);
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 :
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
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.
macam rekursi di atas. Kasus ini digunakan untuk menghitung nilai m2 + (m+1)2 +
355
GDR(5,10)
225
GDR(5,9) +100
110 +64
GDR(5,7)
GDR(5,6)
Bab 1 Dasar Dasar Pemrogaman halaman 15
Gambar 4.1. Pohon pemanggilan rekursi secara menurun
GUR(5,10) 355
25 +
GUR(6,10) 330
36+
GUR(7,10) 294
49+
GUR(8,10) 245
64+
GUR(9,10) 181
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 :
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)
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.
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.
Struct namastruct {
Daftar deklarasi variabel;
}
titik A,B;
Perhatikan progam di bawah ini:
} }
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 << "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);
}
struct titik{
int x = 0;
int y = 0;
};
titik A,B;
}
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);
}
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 :
};
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
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
Tipe bool mempunyai dua alternatif harga yaitu false dan true. False untuk
menggantikan nilai 0, sedangkan true untuk menggantikan nilai 1.
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).
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. }
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:
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.
(16).
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;
};
1. void main() {
2. char *s1 = "aabcadeak";
3. char *s2 = "abfg";
4. char *s3;
5. Himpunan A(s1), B(s2), C(5), D;
Buatlah :
1. konstruktor untuk kelas Himpunan dengan deklarasi baris 5.
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat
Rekursi
Tujuan Pembelajaran:
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
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
B. Kasus diskusi
C. Kasus 3 diskusi
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:
c. Poin a dan b lakukan secara iteratif dalam satu prosedur dengan dua output yaitu
jumlah ganjil dan jumlah genap
Array
Tujuan Pembelajaran
1. mahasiswa memahami array statis dan array dinamis menggunakan 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.
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. };
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.
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.
Fungsi main yang digunakan untuk menguji-coba array statis kelas Array1D
disajikan berikut ini.
(2) yang di-assign ke data member size (4), kemudian dipesan memori sebanyak sz
Kita dapat menyalin dengan cara meng-assign setiap elemen array ke variabel
array yang lain dengan menggunakan konstruktor berikut ini.
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.
Kita dapat membuat operator penugasan khusus array dengan cara meng-
overload operator =. Untuk itu dibuat dengan cara sebagai berikut :
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 :
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 :
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;
Latihan
Di bawah ini diberikan kelas Matrix beserta implementasinya. Pelajarilah
kelas Matrix, meliputi :
1. konstruktor
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. }
Representasi Data
Tujuan Pembelajaran
1. mahasiswa memahami beberapa konsep representasi data
A. Pendahuluan
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).
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).
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).
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).
Setiap element akan dicetak (5) dari awal sampai akhir (4).
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
Ouput :
Length = 0
IsEmpty = 1
List is 2 6
IsEmpty = 0
First element is 2
Length = 2
Deleted element is 2
List is 6
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>;
Kelas ChainNode mempunyai dua data member yaitu data untuk menyimpan data,
dan link untuk menunjuk (menyambung) elemen berikutnya.
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.
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.
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-
Untuk kasus k tidak pada posisi pertama, gambar logiknya adalah sebagai berikut
Kondisi awal :
p p->link
first
‘B’’ ‘C’’ ‘E’’
(10) p p->link
first
‘B’’ ‘C’’ ‘E’’
y
‘D’’
Untuk kasus k pada posisi pertama, gambar logiknya adalah sebagai berikut :
Kondisi awal :
y first
‘B’’ ‘C’’ ‘E’’
(13) p p->link
y first
‘B’’ ‘C’’ ‘E’’
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.
Member data ada dua yaitu first yang digunakan untuk menunjuk elemen
pertama (20) dan menunjuk elemen terakhir (21).
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;}
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 :
{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;}
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. };
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. }
List is 1 2 3 4 5 6
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) {
// 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;
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat
Link list
Tujuan Pembelajaran:
Pra syarat:
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:
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
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
data 1 2
indeks 0 1 2 3 4
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
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
Isi elemen : 1
Pernyataan:
mengubah penunjuk jalan dari objek data 1 ke objek berikutnya (yaitu objek data 2)
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
delete hapus;
Dengan demikian pointer A hanya memiliki 1 elemen yaitu objek 2, objek yang berisi elemen
2
2. Cobalah menyusun gambar logika beserta pernyataan C++ untuk menghapus elemen
di belakang nya
Latihan
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat
Tujuan pembelajaran
Pra Syarat
1. Mahasiswa menguasai operasi dasar link list (menambah dan menghapus elemen
dengan berbagai variasinya)
Circular link list di definisikan sebagai link list yang komponen elemen terakhirnya (pointer)
bukan null (link list biasa) namun menunjuk elemen pertama
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;
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
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:
A-> sebelum = 0;
A-> data = 1;
Dengan demikian kita telah memiliki doubly link list A yang memiliki 1 elemen.
Dengan cara yang sama kita akan membuat Node baru dengan variabel B yang di isi data 2
sebagai berikut:
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
B-> berikut = A;
A-> sebelum = 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
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
Stack (Tumpukan)
Tujuan Pembelajaran
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).
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.
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. }
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.
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.
Kelas Node mempunyai dua data member yaitu data digunakan untuk
menyimpan informasi (9), dan pointer link yang digunakan untuk menunjuk elemen
berikutnya.
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. }
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;}
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
Dari perilaku menara Hanoi di atas, kita buat kelas Hanoi dengan
memanfaatkan kelas Stack (berada pada file stack.h) berikut.
Antrian
Tujuan Pembelajaran
1. Mahasiswa memahami konsep antrian
A. Pendahuluan
Bila ada “kebijakan” lain, misal adanya prioritas tertentu priority queue.
depan
belakang
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
belakang
instan
elemen linear list terurut, yang terdepan dinamakan depan (front), yang
operasi
IsFull() : mengembalikan true jika queue penuh, false jika tidak penuh
Untuk melihat elemen terakhir dari antrian cukup mengakses elemen pada posisi
rear (belakang) (4) dari array queue.
Kelas Node mempunyai dua data member yaitu data untuk menyimpan data
bertipe T dan link suatu pointer yang digunakan untuk menunjuk ke suatu node.
Destruktor kelas LinkedQueue menghapus elemen (7) demi elemen (5) dari depan
(5 dan 8).
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. }
Pointer yang menunjuk queue yang telah ditambah elemen baru dikembalikan
(12).
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 :
2 2 (3,4) (1,2) 6
3 2 (1,4) (2,4) 8
4 2 (3,1) (2,3) 4
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).
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
ini.
b. Tidak diperkenankan ada yang sama dengan Pretest dan contoh yang dibuat
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
1. Elemen yang paling depan akan di layani lebih dulu. Elemen berikutnya di layani
mengikuti urutan dari antrian
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
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.
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.
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 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
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
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
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) :
N N
N1 N2 Nk N1 N2 Nk
Tingkat/level
1 H
2 A K
3 C J L
4 B D
Anchestor(L) = A, C, G
A A
B C D D C D
A
C B
G
E
F L
J K
M
H
D
N O
I
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 :
B C
D E F G
A A
B B
C C
D D
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 .
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
Kunjungan dilakukan pada setiap node tepat satu kali (binary tree traversal)
Preorder
Inorder
B C
D E F
? G H I
Contoh running :
1) H
A K
C J L
3) 7) 8)
4) 5)
Hasil kunjungan :
HACBDKJL
Urutan kunjungan :
Kunjungi cabang
kanan Urutan langkah non rekursif
:
1. Masukkan akar ke stack, bergerak ke cabang kiri
1) A 7) K
3) C 6) J 8) L
B D
2) 4)
A K
C J L
B D
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
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"
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. #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;
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. #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;}
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.
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. #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 = ";
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
+ 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)
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 {
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. }
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
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 :
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”
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;
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. }
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
:
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
598–71-*+7*
a. Gambarkan operasi push dan pop dalam pushdown stack dari notasi postfix di atas [10]
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)
Diberikan procedure iteratif untuk mencetak setiap elemen dari array berikut:
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] Menggunakan gambar yang sama, tulislah kode untuk menghapus elemen ‘e’
__________________________________________________
halaman 186
FM-UAD-PBM-04-16/R1
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 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]
[Nilai 20]
258–*24/72–3**+
a. konstruksikan pohon ekspresi dari notasi postfiks di atas [Nilai 10]
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]
halaman 188
FM-UAD-PBM-04-16/R1
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
598–71-*+7*
d. [Nilai 10] Gambarkan operasi push dan pop dalam pushdown stack dari notasi postfix di atas
Diketahui array A bertipe int, maksimum banyaknya data array A adalah 5. Array A berisi data :
8 3 4 7 2
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
[Konstruksi Struktur data dan reperesentasi data link list – Nilai 30]
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++.
Diberikan procedure iteratif untuk mencetak setiap elemen dari array A berikut:
halaman 190
FM-UAD-PBM-04-16/R1
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.
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
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
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]
halaman 192
FM-UAD-PBM-04-16/R1
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
598–71-*+7*
g. [Nilai 10] Gambarkan operasi push dan pop dalam pushdown stack dari notasi postfix di atas
Diketahui array A bertipe int, maksimum banyaknya data array A adalah 5. Array A berisi data :
8 3 4 7 2
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
[Konstruksi Struktur data dan reperesentasi data link list – Nilai 30]
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
Diberikan procedure iteratif untuk mencetak setiap elemen dari array A berikut:
halaman 194
FM-UAD-PBM-04-16/R1
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
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
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
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!
halaman 195
FM-UAD-PBM-04-16/R1
halaman 196
DAFTAR PUSTAKA
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: