LAPORAN PRAKTIKUM
ALGORITMA DAN STRUKTUR DATA II
MODUL V
BINARY TREE (POHON BINER)
Disusun Oleh :
Syukur Jaya Mendrofa 201501072
Kelas: C
Dosen Pengampu :
Oskar Ika Adi Nugroho, ST., MT
JURUSAN SISTEM INFORMASI
SEKOLAH TINGGI ILMU KOMPUTER “YOS SUDARSO”
PURWOKERTO
BAB I
DASAR TEORI
POHON BINER (BINARY TREE)
Pohon biner adalah sebuah tree yang pada masing-masing simpulnya hanya dapat memiliki maksimum 2 (dua) simpul anak, tidak boleh lebih. Pada pohon biner, umumnya kedua node anak (child) disebut dengan posisinya, yaitu subordinat kiri (left child) dan subordinat kanan (right child).
OPERASI PADA POHON BINER
Operasi pada binary tree merupakan satu rangkaian proses yang dapat dibagi menjadi beberapa bagian operasi (fungsi) seperti:
1. Inisisalisasi.
2. Pembuatan sebuah node. 3. Pembuatan node akar.
4. Penambahan (insert) node baru kedalam sebuah tree. 5. Penghapusan (delete) node dari sebuah tree.
6. Pembacaan atau penelusuran binary tree.
Pembagian ini bukan berdasarkan urutan proses, namun hanya berdasarkan fungsinya yang berbeda.
PROSES INISIALISASI
Inisialisasi yang dimaksud adalah pemberian nilai awal pada suatu variabel atau kondisi yang dapat digunakan sebagai ciri suatu kondisi.
Instruksi dasar untuk inisisalisasi.
Root = NULL; P=NULL;
Inisisalisasi bila ditulis dalam sebuah fungsi.
//Nama fungsi Inisisalisasi
void Inisialisasi() { Root=NULL;
P=NULL;
}
PEMBUATAN SEBUAH NODE
Fungsi untuk Pembuatan Sebuah Node.
void BuatSimpul(char X){
P=(Simpul*)malloc(sizeof(Simpul)); If(P != NULL)
{ P->INFO=X;
P->Left=NULL; P->Right=NULL;
}
else
{ printf(“Pembuatan Node Gagal”);
Exit(1);
}
}
Dengan fungsi ini terbentuk sebuah node yang ditunjuk oleh pointer P dengan ilustrasi sebagai berikut:
Penting : Bila pembuatan node gagal karena suatu hal, misalnya karena keadaan memory yang sudah penuh, maka pointer P akan berisi NULL. Bila hal ini terjadi maka dilayar akan tercetak pesan “Pembuatan Node Gagal”, dan proses dihentikan dengan exit(1). Pada program aplikasi tentunya tidak sesederhana ini, tapi disesuaikan dengan sifat dan kebutuhan aplikasi.
MENJADIKAN SEBUAH NODE SEBAGAI NODE AKAR SUATU TREE
Fungsi untuk Menjadikan Sebuah Node Sebagai Node Akar.
{ if(P != NULL) { Root=P;
Root->Left=NULL;
Root->Right=NULL;
} else
printf(“\n Node Belum Dibuat”);
} else
printf(“Pohon Sudah Ada”);
}
Hasil fungsi diatas dapat diilustrasikan sebagai berikut:
BAB II
TUGAS
1. Program mencari data yang telah dimasukkan
Listing Program
#include <iostream> using namespace std; struct BstNode
BstNode* GetNewNode(int data) {
BstNode* newNode = new BstNode(); newNode->data = data;
newNode->left = newNode->right = NULL; return newNode;
}
BstNode* Insert(BstNode* root, int data) {
if (root == NULL) {
root = GetNewNode(data); }
//jika data yang dimasukan lesser, //masuk ke left subtree
else if (data <= root->data) {
root->left = Insert(root->left, data); }
//else, masuk ke right subtree else
{
root->right = Insert(root->right, data); }
return root; }
bool Search(BstNode* root, int data) {
if (root == NULL) {
return false; }
{
return true; }
else if (data <= root->data) {
return Search(root->left, data); }
else {
return Search(root->right, data); }
}
int main() {
BstNode* root = NULL; root = Insert(root, 100); root = Insert(root, 50); root = Insert(root, 200); root = Insert(root, 300); root = Insert(root, 20); root = Insert(root, 150); root = Insert(root, 70); root = Insert(root, 180); root = Insert(root, 120); root = Insert(root, 30); int number;
cout << "Masukkan bilangan yang mau dicari : \n"; cin >> number;
if (Search(root, number) == true) cout << "Ketemu\n"; else
cout << "Tidak ketemu\n"; system("pause");
return 0; }
Analisa program 1
#include <iostream> => #include<iostream> suatu perintah yang digunakan untuk mengatur compiler agar membaca berkas header yang disertakan dibelakang kata
include yakni dalam program ini <iostream> saat pelaksanaan kompilasi.
using namespace std; => using namespace std; menyatakan kepada compiler bahwa program menggunakan namespace bernama std; namespace fungsinya untuk mengelompokkan elemen-elemen ke dalam sebuah nama. std adalah nama bawaan yang digunakan pada semua pustaka standar C++. Contohnya untuk menampilkan keluaran berupa cout, endl.
struct BstNode => tipe data struct dengan BstNode.
BstNode* left; => anggota struct dengan tipe data ‘BstNode, variable pointer dengan
nama variable ponterleft.
BstNode* right; => anggota struct dengan tipe data ‘BstNode, variable pointer dengan
nama variable ponterright.
BstNode* GetNewNode(int data) => fungsi untuk menyimpan alamat node baru yang
akan di cari
{//awal fungsi BstNode* GetNewNode(int data)
BstNode* newNode = new BstNode(); //untuk menginisialisasi nilai BstNode* newNode yaitu sama dengan new BstNode().
newNode->data = data; //menyimpan alamat data.
newNode->left = newNode->right = NULL; //menginisialisasi alamat sebelah kiri dan sebelah kanan sama dengan 0.
return newNode; //nilai yang akan dikembalikan adalah nilai yang telah disimpan di dalam newNode.
}//akhir fungsi BstNode* GetNewNode(int data)
BstNode* Insert(BstNode* root, int data) => fungsi untuk menyimpan alamat node
baru yang dimasukkan.
{//awal fungsi BstNode* Insert(BstNode* root, int data) if (root == NULL) //jika alamat akar = 0.
{//awal if
root = GetNewNode(data); //nilai alamat akar = memasukkan nilai alamat node baru yang akan di cari
}//akhir if
else if (data <= root->data)//jika nilai dialamat akar data lebih kecil atau sama dengan nilai yang sedang di cari.
{//awal else if
root->left = Insert(root->left, data); //inisialisasi root->left yaitu sama dengan memanggil fungsi BstNode* Insert(BstNode* root, int data)
}//akhir else if
Else jika (root == NULL) dan jika (data <= root->data) maka: {//awal else
root->right = Insert(root->right, data); //inisialisasi root->right yaitu sama dengan memanggil fungsi BstNode* Insert(BstNode* root, int data)
}//akhir else
return root; //nilai kembalian pada fungsi ini.
}// akhir fungsi BstNode* Insert(BstNode* root, int data)
bool Search(BstNode* root, int data) => fungsi Boolean dengan nama fungsi Search yaitu fungsi untuk mencari data yang akan dimasukkan.
{//awal fungsi boolean
if (root == NULL) //jika root == 0 {//awal if
}//akhir if
else if //jika tidak
(root->data == data) //alamat data sama dengan data yang sudah ada. {//awal else if
return true; //maka nilai kembalian true, lanjut ke bawah. }//akhir else if
else if //jika tidak
(data <= root->data)// data yang dimasukkan lebih kecil dari data yang sudah ada. {//awal else if
return Search(root->left, data);// maka nilai kembaliannya data dicari di posisi sebelah kiri.
}//akhir else if
Else//kalau tidak dari pernyataan diatas maka {//awal else
return Search(root->right, data); maka nilai kembaliannya data dicari di posisi sebelah kanan.
}//akhir else
}//akhir fungsi boolean
int main()//fungsi utama {//awal tubuh fungsi utama
BstNode* root = NULL; //menginisialisasi bahwa alamat akar selalu Null. root = Insert(root, 100);
root = Insert(root, 50); root = Insert(root, 200); root = Insert(root, 300); root = Insert(root, 20); root = Insert(root, 150); root = Insert(root, 70); root = Insert(root, 180); root = Insert(root, 120); root = Insert(root, 30);
pohon biner dari data yang telah dimasukkan di dalam program di atas :
oleh karena itu, jika data yang akan dimasukkan lebih kecil dari pada 100 maka program akan mencari data tersebut pada posisi sebelah kiri, jika data yang dimasukkan ada maka output akan menampilkan ketemu, jika data yang dimasukkan tidak ada yang sama dengan data yang telah ada maka output akan menampilkan Tidak ketemu.
Dan jika data yang akan dimasukkan lebih besar dari pada 100 maka program akan mencari data tersebut pada posisi sebelah kanan, jika data yang dimasukkan ada maka output akan menampilkan ketemu, jika data yang dimasukkan tidak ada yang sama dengan data yang telah ada maka output akan menampilkan Tidak ketemu.
int number; //variable untuk menyimpan angka yang akan dicari. cout << "Masukkan bilangan yang mau dicari : \n"; //menampilkan cin >> number; menyimpan angka yang akan dicari
if (Search(root, number) == true) //jika data yang dicari ditemukan maka True cout << "Ketemu\n"; //tampilkan ketemu
else //kalau tidak maka
cout << "Tidak ketemu\n";// tampilkan tidak ketemu.
system("pause");//program berhenti sejenak.
return 0; // Pernyataan bahwa nilai balik program adalah nol. Nol biasa digunakan untuk menyatakan bahwa program berhasil melaksanakan tugas yang diembannya.
}//akhir tubuh fungsi utama
2. Program 2
Listing Program
#include <iostream> #include <stack> #include <conio.h> using namespace std;
class Simpul {
public:
int iData; //item data (kunci) double dData; //item data
//konstruktor
void tampilSimpul() //menampilkan simpul, contoh {75, 7.5} {
cout << "{" << iData << ", " << dData << "} "; }
}; //akhir kelas Simpul
class Pohon
Simpul* cari(int kunci) //mencari simpul dengan kunci tertentu { //(asumsi pohon tak-kosong)
if(pSkrg == NULL) //jika tidak ada anak, return NULL; //tidak ditemukan
}
return pSkrg; //ditemukan } //akhir cari()
void sisip(int id, double dd) //menyisipkan simpul baru {
Simpul* SimpulBaru = new Simpul; //menciptakan simpul baru SimpulBaru->iData = id; //menyisipkan data
SimpulBaru->dData = dd;
if(pAkar==NULL) //tidak ada simpul pada akar pAkar = SimpulBaru;
Simpul* pSkrg = pAkar; //diawali di akar Simpul* pInduk;
while(true) //(keluar scr internal) {
pInduk = pSkrg;
if(id < pSkrg->iData) //ke kiri? {
pSkrg = pSkrg->pAnakKiri; if(pSkrg == NULL) //jika di akhir, { //sisip di kiri
pInduk->pAnakKiri = SimpulBaru; return;
}
} //akhir if ke kiri
else //atau ke kanan? {
pSkrg = pSkrg->pAnakKanan; if(pSkrg == NULL) //jika di akhir, { //sisip di kanan
pInduk->pAnakKanan = SimpulBaru; return;
}
} //akhir else ke kanan } //akhir while
} //akhir else tidak di akar } //akhir sisip()
void jelajah(int tipeJelajah) {
switch(tipeJelajah) {
case 1: cout << "\nPenjelajahan Preorder: "; preOrder(pAkar);
break;
case 2: cout << "\nPenjelajahan Inorder: "; inOrder(pAkar);
break;
case 3: cout << "\nPenjelajahan Postorder: "; postOrder(pAkar);
break; }
cout << endl; }
void preOrder(Simpul* pAkarLokal) {
if(pAkarLokal != NULL) {
preOrder(pAkarLokal->pAnakKiri); //anak kiri preOrder(pAkarLokal->pAnakKanan); //anak kanan }
}
void inOrder(Simpul* pAkarLokal) {
if(pAkarLokal != NULL) {
inOrder(pAkarLokal->pAnakKiri); //anak kiri
cout << pAkarLokal->iData << " "; //menampilkan simpul inOrder(pAkarLokal->pAnakKanan); //anak kanan
} }
void postOrder(Simpul* pAkarLokal) {
if(pAkarLokal != NULL) {
postOrder(pAkarLokal->pAnakKiri); //anak kiri postOrder(pAkarLokal->pAnakKanan); //anak kanan cout << pAkarLokal->iData << " "; //menampilkan simpul } int jumSpasi = 32;
bool apaBarisKosong = false;
cout <<"..."; cout << endl;
while(apaBarisKosong==false) {
stack<Simpul*> tumpukanLokal; apaBarisKosong = true;
for(int j=0; j<jumSpasi; j++) cout << " ";
while(tumpukan.empty()==false) {
Simpul* temp = tumpukan.top(); tumpukan.pop();
if(temp != NULL) {
tumpukanLokal.push(temp->pAnakKiri); tumpukanLokal.push(temp->pAnakKanan);
if(>pAnakKiri != NULL || temp->pAnakKanan != NULL)
apaBarisKosong = false; }
else {
cout << "--";
tumpukanLokal.push(NULL); tumpukanLokal.push(NULL); }
for(int j=0; j<jumSpasi*2-2; j++) cout << " ";
}
cout << endl; jumSpasi /= 2;
while(tumpukanLokal.empty()==false) {
tumpukan.push( tumpukanLokal.top() ); tumpukanLokal.pop();
} }
cout <<"..."; cout << endl;
} //akhir tampilPohon()
void hapus() //menghapus semua simpul { hapusRekursif(pAkar); } //mulai dari akar
void hapusRekursif(Simpul* pAkarLokal) //menghapus simpul-simpul {
if(pAkarLokal != NULL) {
hapusRekursif(pAkarLokal->pAnakKiri); //subpohon kiri hapusRekursif(pAkarLokal->pAnakKanan); //subpohon kanan
delete pAkarLokal; //menghapus simpul ini }
} }; //akhir kelas Pohon
int main() {
int nilai;
Simpul* ditemukan;
Pohon pohon; //menciptakan Pohon
pohon.sisip(50, 5.0); //menyisipkan pohon-pohon pohon.sisip(25, 2.5);
while(pilihan != 'k') //berinteraksi dengan pengguna { //sampai pengguna mengetikkan 'k'
cout << "masukkan huruf pertama dari ";
cout << "tampil, sisip, cari, jelajah, atau keluar: "; cin >> pilihan;
switch(pilihan) {
case 't': //menampilkan Pohon pohon.tampilPohon(); break;
case 's': //menyisipkan sebuah Simpul
cout << "Masukkan nilai yang akan disisipkan: "; cin >> nilai;
pohon.sisip(nilai, nilai + 0.9); break;
case 'c': //mencari sebuah Simpul
cout << "Masukkan nilai yang akan dicari: "; cin >> nilai;
ditemukan = pohon.cari(nilai);
if(ditemukan != NULL) {
cout << "Ditemukan: "; ditemukan->tampilSimpul(); cout << endl;
} else
cout << "Tidak ditemukan." << nilai << endl; break;
case 'j': //menjelajah Pohon
<< "2 = inorder, 3 = postorder): "; cin >> nilai;
pohon.jelajah(nilai); break;
case 'k': //keluar program pohon.hapus(); cout << endl; break;
default:
cout << "Entri tak-valid\n"; } //akhir switch
} //akhir while
getch();
system("pause"); return 0;
} //akhir main()
HASILOUTPUT :
Algoritma program 2:
1. Pertama sekali program masuk kedalam fungsi utama/int main ( )
3. Ketiga setelah kita memasukkan pilihan contoh kita memilih untuk menampilkan = t, kemudian program akan memanggil fungsi pohon.tampilPohon();
4. Keempat program akan kembali menampilkan menu pilihan yang ada di dalam fungsi utama.
5. Kelima setelah kita memasukkan pilihan contoh kita memilih untuk menyisipkan = s, kemudian program akan menampilkan “Masukkan nilai yang akan disisipkan: “, lalu nilai yang telah dimasukkan di proses dalam fungsi pohon.sisip(nilai, nilai + 0.9); 6. Keenam program akan kembali menampilkan menu pilihan yang ada di dalam fungsi
utama.
7. Ketujuh setelah kita memasukkan pilihan contoh kita memilih untuk menampilkan = t, kemudian program akan memanggil fungsi pohon.tampilPohon(); maka pada tampilan kali ini ada penambahan data yang telah disisipkan tadi.
8. Kedelapan program akan kembali menampilkan menu pilihan yang ada di dalam fungsi utama.
9. Kesembilan setelah kita memasukkan pilihan contoh kita memilih untuk mencari = c, kemudian program akan menampilkan “Masukkan nilai yang akan dicari: “, lalu nilai yang telah dimasukkan di proses dalam fungsi pohon.cari(nilai)= ditemukan, kemudian jika data yang dimasukkan ada didalam pohon biner maka akan di tampilkan ditemukan->tampilSimpul(); jika tidak ada maka program akan menampilkan “Tidak Ditemukan”.
10. Kesepuluh program akan kembali menampilkan menu pilihan yang ada di dalam fungsi utama.
11. Kesebelas setelah kita memasukkan pilihan contoh kita memilih untuk menjelajah = j, maka program akan menampilkan “Masukkan tipe jelajah (1 = preorder, " << "2 = inorder, 3 = postorder): ", kemudian ketika kita memilih nilai 1 maka program akan menyimpan nilai yang telah kita masukkan dan memproses kedalam fungsi
pohon.jelajah(nilai);
Jika kita pilih 1 maka program akan memanggil fungsi preOrder(pAkar); Jika kita pilih 2 maka program akan memanggil fungsi inOrder(pAkar); Jika kita pilih 3 maka program akan memanggil fungsi postOrder(pAkar);
void jelajah(int tipeJelajah) {
switch(tipeJelajah) {
case 1: cout << "\nPenjelajahan Preorder: "; preOrder(pAkar);
break;
case 2: cout << "\nPenjelajahan Inorder: "; inOrder(pAkar);
break;
case 3: cout << "\nPenjelajahan Postorder: "; postOrder(pAkar);
break; }
12. Keduabelas program akan kembali menampilkan menu pilihan yang ada di dalam fungsi utama.
13. Ketigabelas setelah kita memasukkan pilihan contoh kita memilih untuk keluar program = k, lalu program akan memanggil fungsi pohon.hapus();.
BAB III
KESIMPULAN
Pohon biner adalah sebuah tree yang pada masing-masing simpulnya hanya dapat memiliki maksimum 2 (dua) simpul anak, tidak boleh lebih. Pada pohon biner, umumnya kedua node anak (child) disebut dengan posisinya, yaitu subordinat kiri (left child) dan
subordinatkanan (right child).
Fungsi inisialisasi harus dilaksanakan sebelum operasi yang lain. Pointer Root ketika dideklarasikan isinya sudah ada, tapi nilainya tidak diketahui. Pointer Root perlu diisi dengan NULL karena Pointer Root ini akan dijadikan tanda. Bila isinya NULL, berarti tree belum ada. Bila isinya bukan NULL berarti tree sudah ada, dimana node akar sedang ditunjuk oleh pointer Root.
#include <iostream>
struct BstNode
{
int data;
BstNode* left;
BstNode* right;
};
BstNode* GetNewNode(int data)
{
BstNode* newNode = new BstNode();
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
BstNode* Insert(BstNode* root, int data)
{
if (root == NULL)
{
root = GetNewNode(data);
}
//jika data yang dimasukan lesser,
//masuk ke left subtree
else if (data <= root->data)
{
}
//else, masuk ke right subtree
else
{
root->right = Insert(root->right, data);
}
return root;
}
bool Search(BstNode* root, int data)
{
if (root == NULL)
{
return false;
}
else if (root->data == data)
{
return true;
}
else if (data <= root->data)
{
return Search(root->left, data);
}
else
return Search(root->right, data);
}
}
int FindMin(BstNode* root)
{
if (root == NULL)
{
cout << "Error : Tree is Empty \n";
return-1;
}
else if (root->left == NULL)
{
return root->data;
}
return FindMin(root->left);
}
int FindMax(BstNode* root)
{
if (root == NULL)
{
return-1;
}
else if (root->right == NULL)
{
return root->data;
}
return FindMax(root->right);
}
int main()
{
BstNode* root = NULL;
root = Insert(root, 100);
root = Insert(root, 50);
root = Insert(root, 200);
root = Insert(root, 300);
root = Insert(root, 20);
root = Insert(root, 150);
root = Insert(root, 70);
root = Insert(root, 180);
root = Insert(root, 120);
root = Insert(root, 30);
int number;
cin >> number;
if (Search(root, number) == true)
{
cout << "Ketemu\n";
cout << "Nilai Terkecil : " << FindMin(root->left) << endl;
cout << "Nilai Terbesar : " << FindMax(root->right) << endl;
}
else
cout << "Tidak ketemu\n";
system("pause");
return 0;