Root - Google Drive

Download Report

Transcript Root - Google Drive

FATHER
INFO
LEFT
RIGHT
INFO
LEFT
INFO
RIGHT
LEFT
RIGHT
INFO
LEFT
RIGHT
atau
typedef struct Node {
int INFO;
struct Node *LEFT;
struct Node *RIGHT;
};
typedef struct Node
Simpul;
typedef struct Node
struct Node
int INFO;
struct Node
};
typedef struct Node
{
*LEFT;
*RIGHT;
Simpul;
INFO
LEFT
RIGHT
atau
typedef struct Node {
int INFO;
struct Node *LEFT;
struct Node *RIGHT;
};
typedef struct Node
Simpul;
typedef struct Node
struct Node
int INFO;
struct Node
};
typedef struct Node
{
*LEFT;
*RIGHT;
Simpul;
FATHER
INFO
LEFT
RIGHT
typedef struct Node {
struct Node *FATHER;
int INFO;
struct Node *LEFT;
struct Node *RIGHT;
};
typedef struct Node Simpul;
atau
typedef struct Node {
int INFO;
struct Node *FATHER;
struct Node *LEFT;
struct Node *RIGHT;
};
typedef struct Node Simpul;
6.1.1
Beberapa contoh pohon biner
dengan kedalaman (depth) d = 3.
root
level
0
A
B
1
C
D
E
J
F
K
Gambar-6.2 a
Stricly Binary Tree
G
2
3
level
A
B
0
C
D
2
E
J
1
K
Gambar-6.2 b
Stricly Binary Tree
3
root
level
A
0
B
D
H
E
I
1
C
J
F
K
L
2
G
M
N
O
3
depth = 3
Gambar-6.2 c
Complete Binary Tree
root
level
A
0
B
D
H
E
I
1
C
J
F
K
L
G
M
N
Gambar-6.2 d
Almost Complete Binary Tree
2
3
6.2 Penomoran Simpul Pohon Biner
n
2n
2n+1
5
10
11
A
B
D
0
0
C
2
E
4
1
1
3
F
5
G
H
I
10
11
14
2
3
1
4
5
A B C D E
6
7
F
2
7
3
8
9
10 11 12 13 14
G H
I
15
6.4 Proses (Operasi) Pada Pohon Biner.
1.
2.
3.
4.
5.
6.
Insialisasi
Pembuatan sebuah simpul.
Pembuatan simpul akar
Penambahan (insert) simpul kedalam sebuah pohon
Penghapusan (delete) simpul dari sebuah pohon
Pembacaan / Penelusuran pohon biner
Mendeklarasikan struktur Simpul
struct Node
Struktur
SIMPUL
{ struct Node *Left;
INFO
char INFO;
struct Node *Right;
};
typedef struct Node Simpul;
Left
Right
Simpul *Root, *P, *Q, *R;
char X;
*Root
*P
*Q
*R
Pointer Root digunakan khusus menunjuk simpul akar.
Pointer P
digunakan khusus menunjuk simpul yang baru dibuat
Pointer Q, R digunakan sebagai pointer pembantu
Pointer-pointer lain dapat ditambahkan bilamana diperlukan
Selain itu dideklarasi juga sebuah variabel X
bertipe sama dengan tipe INFO yaitu tipe : char
X
6.6. Pembuatan Sebuah Simpul
P
Fungsi untuk Pembuatan Sebuah Simpul
void BuatSimpul( char X)
{
P = (Simpul*) malloc(sizeof(Simpul));
if(P != NULL)
{ P->INFO = X;
P->Left = NULL;
P->Right = NULL;
}
else
{ printf(“Memory Heap Full”);
exit(1);
}
}
A
Instruksi Membuat Sebuah Simpul
P = (Simpul*) malloc(sizeof(Simpul));
P
P
P->INFO
P->RIGHT
P->LEFT
Mengisi P->INFO dengan data
Misal variabel X
Berisi nilai
Karakter ‘A’
P->INFO = X;
P
A
Mengisi P->LEFT dan P->RIGHT
Dengan NULL
P->Left = NULL;
P->Right = NULL;
P
A
6.7 Menjadikan Sebuah Simpul Sebagai Simpul Akar Suatu Pohon
Fungsi untuk Menjadikan
Simpul Sebagai Simpul Akar
Sebuah
void BuatSimpulAkar( )
{ if(Root == NUL)
{ if(P != NULL)
{ Root = P;
Root->Left = NULL;
Root->Right = NULL;
}
else
printf(“\n Simpul Belum Dibuat”);
}
else
printf(“Pohon Sudah Ada”);
}
Root
P
A
6.8 Menambahkan (Insert) Sebuah Simpul
ke Pohon Yang Sudah Ada.
6.8.1 Insert urut nomor simpul atau insert level per level.
P
Root
Root
A
A
B
P
B
6.8 Menambahkan (Insert) Sebuah Simpul
ke Pohon Yang Sudah Ada.
6.8.1 Insert urut nomor simpul atau insert level per level.
P
Root
Root
A
A
B
P
B
Root->LEFT= P;
Root
P
A
B
Root
P
A
B
Root
P
A
B
Root->RIGHT = P;
6.8.1 Insert urut nomor simpul
atau insert level per level.
Root
Root
Root
A 1
A 1
B
B 2
b
Root
A 1
A 1
2
a
Root
C
B
3
D
c
A 1
C
2
3
B 2
D 4
4
C
E
5
d
e
Root
A 1
A 1
B 2
D
4
C
E
5
f
Root
Root
F
6
3
A 1
B 2
D
4
C
E
5
g
F 6
3
G 7
B 2
D
4
C
E
5
H 8
h
F 6
3
G 7
3
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<ctype.h>
#include<math.h>
#include<malloc.h>
struct Node
{ struct Node *Left;
char INFO;
struct Node *Right;
};
typedef struct Node Simpul;
Simpul *P, *Root, *Current;
Simpul *Q[129];
0
*Q
int main()
{ int i, j, Flag;
char X;
clrscr();
Inisialisasi();
X = getche();
BuatSimpul(X);
BuatSimpulAkar();
InsertSimpulUrutNomor();
BacaUrutNomor();
}
128
int main()
{ int i, j, Flag;
char X;
clrscr();
Inisialisasi();
X = getche();
BuatSimpul(X);
BuatSimpulAkar();
InsertSimpulUrutNomor();
BacaUrutNomor();
}
void Inisialisasi ()
{ Root = NULL;
P = NULL;
}
Root
P
int main()
{ int i, j, Flag;
char X;
clrscr();
Inisialisasi();
X = getche();
BuatSimpul(X);
BuatSimpulAkar();
InsertSimpulUrutNomor();
BacaUrutNomor();
}
P
A
void BuatSimpul( char X)
{
P = (Simpul…………………);
P->INFO = X;
P->Left = NULL;
P->Right = NULL;
}
int main()
{ int i, j, Flag;
char X;
clrscr();
Inisialisasi();
X = getche();
BuatSimpul(X);
BuatSimpulAkar();
InsertSimpulUrutNomor();
BacaUrutNomor();
}
P
Root
A
void BuatSimpulAkar( )
{ Root = P;
Root->Left = NULL;
Root->Right = NULL;
}
int main()
{ int i, j, Flag;
char X;
clrscr();
Inisialisasi();
X = getche();
BuatSimpul(X);
BuatSimpulAkar();
InsertSimpulUrutNomor();
BacaUrutNomor();
}
P
void InsertUrutNomor()
{ int i, j, Flag;
char X;
Flag = 0; i=1; j=1;
Q[i] = Root;
while(Flag == 0 && j < 127)
{ X = getche();
-
Root
i++;
}
}
A
void InsertUrutNomor()
{ int i, j, Flag;
char X;
Flag = 0; i=1; j=1;
Q[i] = Root;
while(Flag == 0 && j < 127)
{ X = getche();
i++;
}
}
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Left = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
if(Flag == 0)
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Right = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
}
i++;
void InsertUrutNomor()
{ int i, j, Flag;
char X;
Flag = 0; i=1; j=1;
Q[i] = Root;
while(Flag == 0 && j < 127)
{ X = getche();
-
i++;
}
}
j
i
0
Q
1
n
Root
2
3
4
5
6
7
2n 2n+1
Disini
berisi
alamat
simpul
Akar
(Root)
Disini berisi
alamat
simpul no 5
void InsertUrutNomor()
{ int i, j, Flag;
char X;
Flag = 0; i=1; j=1;
Q[i] = Root;
while(Flag == 0 && j < 127)
{ X = getche();
i++;
}
}
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Left = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
if(Flag == 0)
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Right = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
}
i++;
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Left = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
if(Flag == 0)
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Right = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
}
i++;
Input data untuk diinsert di Q->Left
Input data untuk diinsert di Q->Right
Input
data ke-dua
dan
Insert di
Current->Left
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Left = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
0
Q
Root
Current
Current
1
Root
A
P
Sekarang
Current
masih
sama
dengan
Root
i
j
1
2
Root
P
3
4
2
5
B
6
7
if(Flag == 0)
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Right = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
}
i
0
Q
1
Current
1
Root
A
P
Sekarang
Current
masih
sama
dengan
Root
2
B
3
j
2
Root No.2
Root
Input
Current
data ke-tiga
dan
Insert di
Current->Right
3
P
4
5
6
7
C
void InsertUrutNomor()
{ int i, j, Flag;
char X;
Flag = 0; i=1; j=1;
Q[i] = Root;
while(Flag == 0 && j < 127)
{ X = getche();
Current
1
Sudah
selesai
insert
dua
simpul
-
i++;
Root
A
P
2
B
3
}
}
I++
0
Q
1
i
j
2
3
Root No.2
Root
Current
P
4
5
6
7
C
void InsertUrutNomor()
{ int i, j, Flag;
char X;
Flag = 0; i=1; j=1;
Q[i] = Root;
while(Flag == 0 && j < 127)
{ X = getche();
Current
1
-
Root
A
P
i++;
2
B
3
}
}
I++
0
Q
1
i
j
2
3
Root No.2
Root
Current
P
4
5
6
7
C
Root
Input
data ke-4
{ X = getche();
if(X != '0')
{ BuatSimpul(X);
Current = Q[i];
Current->Left = P;
j++; Q[j] = P;
}
else { // data habis
Flag = 1;
j++; Q[j] = NULL;
}
Current
Pindah
Nunjuk
Simpul
No. 2
kemudian
data ke-4
dan
Insert di
Current->
Left
1
Current
2
0
Q
1
j
2
3
Root No.2
P
4
5
B
P
C
i
A
6
7
4
3
C
void Inisialisasi ()
{ Root = NULL;
P = NULL;
}
void BuatSimpul(char X)
{
}
int main()
{ int i, j, Flag;
char X;
clrscr();
void BuatSimpulAkar( )
{ lihat contoh sebelumnya
}
Inisialisasi();
X = getche();
BuatSimpul(X);
void InsertSimpulUrutNomor()
{
}
BuatSimpulAkar();
InsertSimpulUrutNomor();
BacaUrutNomor();
void BacaUrutNomor()
{
}
}
void BuatSimpul( char X)
{
P = (Simpul*) malloc(sizeof(Simpul));
if(P != NULL)
{ P->INFO = X;
P->Left = NULL;
P->Right = NULL;
}
else
{ printf(“Memory Heap Full”);
exit(1);
}
}
void BacaUrutNomor()
{ int i,j,n,Counter;
i=1; j=1; n=1; Counter=0;
printf(“\n”);
Q[I] = Root;
while(Q[i] != NULL)
{ Current = Q[i];
printf("%c ", Current->INFO);
Counter++;
if(Counter == n)
{ printf(“\n”);
Counter=0; n = n*2;
}
j++; Q[j] = Current->Left;
j++; Q[j] = Current->Right;
i++;
}
void BacaUrutNomor()
{ int i, j, n, Counter;
char X;
i=1; j=1; n=1; Counter=0;
printf(“\n”);
while(Q[i] != NULL)
{ Current = Q[i];
printf("%c ", Current->INFO);
Counter++;
if(Counter == n)
{ printf(“\n”);
Counter=0; n = n*2;
}
i++;
}
}
1
2
4
P
B
C
D
E
I
H
Q
A
J
5
K
6
L
3
F
G
M
N
7
O
6.8.2
Insert Simpul Pada Nomor
Simpul Tertentu.
Root
1
2
4
8
P
16
H
Q
B
D
C
5
I
A
E
6
S
12
K
9
V
W
F
G
L
X
M
Y
19
25
a
50
3
Z
N
7
O
Root
1
A
6
C
6
12
F
L
Y
50
3
a
25
6=
nomor
simpul
F
F=
Nilai
INFO
Root
1
A
6
kanan
C
3
kiri
6
F
kiri
12
L
kanan
Y
kiri
50
a
Q
25
6=
nomor
simpul
F
F=
Nilai
INFO
Root
1
A
6
1
C
3
0
6
F
0
12
Q
L
1
Y
0
50
a
25
6=
nomor
simpul
F
F=
Nilai
INFO
Root
1
A
1
C
0
6
F
0
12
Q
L
1
Y
0
50
a
25
3
4
1
3
0
2
0
1
1
0
0
-1
S
Top
n = 50; Top = -1;
hasil = n;
while(hasil > 1)
{ sisa = n % 2; n = n/2;
hasil = n;
Top++; S[Top] = sisa;
}
4
1
3
0
2
0
1
1
0
0
-1
S
Top
n = 50; Top = -1;
hasil = n;
while(hasil > 1)
{ sisa = n % 2; n = n/2;
hasil = n;
Top++; S[Top] = sisa;
}
50 / 2
=
25
sisa
0
simpan
4
1
3
0
2
0
1
1
0
0
-1
S
0
25 / 2
=
12
sisa
1
simpan
1
12 / 2
=
6
sisa
0
simpan
0
6 / 2
=
3
sisa
0
simpan
0
3 / 2
=
1
sisa
1
simpan
1
Selesai bila hasil = 1
Top
Q = Root;
while(Top > 0 )
{ arah = S[Top]; Top--;
if(arah = 0 )
Q = Q->Left;
else
Q = Q->Right;
}
arah = S[0]; // Top pasti = 0
if(arah == 0 )
Q->Left = P;
else
{ printf(“\n Ada kesalahan”);
printf(“\n unt.simpul no.50”);
printf(“\n harus insert kiri”);
}
Q = Root;
while(Top > 0 && Q != NULL)
{ arah = S[Top]; Top--;
if(arah == 0 )
Q = Q->Left;
else
Q = Q->Right;
}
if(Q != NULL)
{ arah = S[0];
if(arah == 0 )
Q->Left = P;
else
{ printf(“\n Ada kesalahan”);
printf(“\n unt.simpul no.50”);
printf(“\n harus insert kiri”);
}
}
else
printf( “Simpul Tak Bisa Diinsert” );
Root
A
Root
Root
A
1
B
A
1
B
2
Root
A
1
C 3
2
B 2
Root
1
A
C
3
1
B 2
C
a
D 4
c
b
1
A
D 4
C
E
5
f
F 6
3
Root
1
A
B 2
D 4
C
E
5
5
e
Root
B 2
E
d
Root
A
D 4
F 6
3
G 7
B 2
D 4
C
E
5
H 8
g
h
204
1
F 6
3
G
7
3
Perhatikan langkah-langkah dalam usaha menempatkan pointer Q
menunjuk simpul no. 25 (bila ada)
Q = Root;
while(Top > 0 && Q != NULL)
{ arah = S[Top]; Top--;
if(arah == 0 )
Q = Q->Left;
else
Program-b Q = Q->Right;
}
Q
Root
1
12
L
0
6
3
1
F
12
L
0
1
F
6
C
0
4
3
2
3
1
0
1
0
0
1
0
1
S
Bila simpul no.3 tidak ada, maka Q = NULL, sehingga keluar
dari loop, walaupun Top belum menunjuk S[0].
A
L
0
6
F
Q
12
L
0
6
F
C
0
3
3
2
1
Top
S
0
1
Bila simpul no. 6 tidak ada, maka Q = NULL, sehingga keluar
dari loop, walaupun Top belum menunjuk S[0].
Root
A
4
0
1
0
0
1
0
4
1
Root
C
S
Keadaan awal.
Q menunjuk Root,
Top menunjuk S[4]
Q
1
1
1
0
1
Top
12
1
3
Top
Root
Q
A
2
C
0
Root
1
1
0
0
1
0
4
A
3
3
2
1
0
1
0
0
1
0
1
Top
S
12
1
L
0
6
A
4
1
F
C
0
3
Q
1
25
210
2
1
Sampai disini, bila :
Simpul no.25 tidak ditemukan
Maka :
Q = NULL, walaupun
Top menunjuk S[0]
Bila simpul no.12 tidak ada, maka Q = NULL, sehingga
keluar dari loop, walaupun Top belum menunjuk S[0].
3
0
1
0
0
1
0
S
Top
Contoh-6.8.2.d
Berusaha menginsert sebuah simpul baru menjadi Simpul no. 50. Insert dibatalkan bila :
a. Simpul no no.25 atau simpul-simpul sebelum no.25 tidak ada, dan cetak perkataan “Simpul Tak Bisa Diinsert”, “Simpul
Superordinatnya Tidak Ada “, atau
b.
Simpul no.50 sudah ada, dan cetak perkataan “ Simpul no.50 Sudah Ada “.
Root
Langkah-1. (Bagian-1)
Menentukan langkah untuk menuju simpul no.50 yaitu : 1 –
0– 0– 1- 0
dan simpan ke Stack S.
n = 50; Top = -1;
hasil = n;
while(hasil > 1)
{ sisa = n % 2; n = n/2;
hasil = n;
Top++; S[Top] = sisa;
Langkah-2
} atau Program Bagian-2.
1
12
50
L
0
6
1
a
0
A
1
F
C
0
3
3
Q
Y
1
0
0
1
0
4
2
25
1
Top
S
0
Gambar-6.17 b
Gambar-6.17 a
(sambungan Bagian-1).
Q = Root;
while(Top > 0 && Q != NULL)
{ arah = S[Top]; Top--;
if(arah == 0 )
Q = Q->Left;
else
Q = Q->Right;
if(Q} == NULL)
{ printf( “ Simpul Tak Bisa Diinsert “ );
printf( “ Simpul Superordinatnya Tidak Ada” );
}
else { //Q pasti != NULL & tentunya Top pasti = 0
arah = S[0];
if(arah == 0 )
{ if(Q->Left != NULL)
printf(“Simpul no.50 Sudah Ada”);
else
Q->Left = P;
}
else { printf(“\n Ada kesalahan program”);
printf(“\n Untuk Simpul No. 50 “);
printf(“\n Seharusnya isi S[0]=0”);
211
}
Root
1
0
12
50
6
A
1
F
L
1
a
C
0
0
Gambar-6.19
Q
25
3
6.10 Membaca Pohon Biner.
6.10.1 Membaca Pohon Biner level per level urut nomor simpul.
6.10.2 Membaca atau mencari sebuah simpul dengan nomor tertentu.
6.10.1 Membaca Pohon Biner level per level urut nomor simpul.
Perhatikan pohon biner yang diilustrasikan pada empat buah gambar berikut ini :
B
2
4
I
H
P
5
E
K
J
Q
6
F
G
M
L
2
3
C
D
7
N
4
1
E
I
G
K
J
5
N
1
6
7
Gambar-6.24 b
3
C
F
K
J
5
A
B
E
3
C
D
O
A
B
Gambar-6.24 a
2
1
A
1
2
G
M
B
C
7
E
N
A
J
Gambar-6.24 c
3
5
K
Gambar-6.24 d
Pohon –pohon biner diatas, bila dibaca dan dicetak simpul per simpul, dengan pembacaan level per level urut nomor simpul maka :
Untuk pohon pada :
Akan tercetak :
A B C D E F G H I J K L M N O P Q
Gambar-6.24 a
A B C D E G I J K N
Gambar-6.24 b
A B C E F G J K M N
Gambar-6.24 c
Gambar-6.24
d
A (biasanya
B C E J diberi
K
Untuk keperluan algoritma,
maka diperlukan
sebuah array
nama Q) bertipe pointer Simpul, untuk mencatat alamat simpulsimpul. Sebagai contoh, untuk pohon biner yang diilustrasikan dengan Gambar-6.24 d, maka alamat simpul-simpulnya tersimpan dalam
array pointer seperti yang digambarkan pada Gambar-6.25.
Catatan : &A maksudnya alamat simpul A, \0 untuk menyatakan NULL
0
Q
1
&A
2
3
&B
4
&C
\0
5
6
&E
\0
Gambar-6.25
217
7
\0
8
\0
9
\0
10
&J
11
&K
12
\0
#include<stdio.h>
#include<malloc.h>
#include<conio.h>
struct Node
{ struct Node *Left;
char INFO;
struct Node *Right;
};
typedef struct Node Simpul;
Simpul *Q[50];
Simpul *Current, *Akar, *P;
int i,j;
char X;
- disini membuat pohon binernya
- ( tidak dibahas ).
-
// mencetak isi simpul-simpul pohon biner
for(i=0; i<=49; i++)
{ Q[i] = NULL; }
Q[0] = Akar;
i=0; j=0;
while(Q[i] != NULL)
{ Current = Q[i];
printf("%c ", Current->INFO);
if(Current->Left != NULL)
{ j++;
Q[j] =Algoritma
Current->Left;
mencetak simpul level per
}
level urut nompor simpul
if(Current->Right != NULL)
{ j++;
Q[j] = Current->Right;
218
}
Menyiapkan array Q
Bertipe Pointer untuk menunjuk Simpul
Disini membuat simpul-simpul pohon biner. Bagaimana
membuat pohon biner sudah diterangkan sebelumnya.
Mengisi seluruh elemen array Q
dengan NULL.
Untuk pertama kali, alamat simpul akar disimpan di Q[0].
Alamat simpul akar pasti bukan NULL.
Apakah simpul subpohon kiri ada ?
Menyimpan
alamat
simpul
subpohon kiri (kalau ada) ke
dalam array Q
Menyimpan alamat simpul subpohon kanan (kalau ada)
ke dalam array Q
//trilvl2.cpp
#include<stdio.h> #include<malloc.h>
#include<conio.h>
struct Node
{ struct Node *Left;
char INFO;
struct Node *Right;
};
typedef struct Node Simpul;
Simpul *Q[50], *Current, *Akar, *P;
int i,j; char X;
Ketik dan RUN program ini untuk melihat hasil
pembacaan simpul pohon biner level per level urut
nomor simpul.
Instruksi-instruksi untuk meng-insert simpul sengaja
dibuat secara ‘manual’ hanya untuk memudahkan
membuat pohon.
Meng-insert simpul secara ‘program’ dapat dilihat pada
contoh sebelumnya.
void Inisialisasi()
{ Akar = NULL; P = NULL;
}
void BuatSimpul(char X)
{ P = (Simpul*) malloc(sizeof(Simpul));
if(P !=NULL)
{ P->INFO = X; P->Left = NULL;
P->Right = NULL;
}
else
printf("Simpul Tak Bis Dibuat ");
}
void BuatAkar()
{ if (Akar == NULL)
{ if(P != NULL)
{Akar = P; }
else
{ printf("Simpul Belum Ada"); }
}
else { printf("Akar Sudah Ada "); }
}
void main()
{ Inisialisasi();
BuatSimpul('A'); BuatAkar();
BuatSimpul('B'); Akar->Left = P;
BuatSimpul('C'); Akar->Right = P;
BuatSimpul('G'); Akar->Right->Right = P;
BuatSimpul('E'); Akar->Left->Right = P;
BuatSimpul('F'); Akar->Right->Left = P;
BuatSimpul('L'); Akar->Right->Left->Left = P;
BuatSimpul('M'); Akar->Right->Left->Right = P;
for(i=0;i<=49;i++)
Q[0] = Akar;
{ Q[i] = NULL; }
Gambar pohon yang dibuat
‘manual’ oleh program ini
secara
Akar
A
B
C
E
F
L
G
M
Instruksi-instruksi membuat atau menginsert simpulsimpul pohon secara ‘manual’ Cara seperti ini tidak
berlaku umum.
Digunakan disini hanya untuk memudahkan
membuat pohon seperti pada gambar diatas.
Program ini akan membuat Pohon sepert diatas,
Dan mencetak level per level sehingga tercetak ;
A B C E F G L M
219
Membaca Pohon Biner level per level urut nomor pada pohon yang menggunakan pointer link pada level yang sama.
Algoritma mencetak simpul level per level sama dengan menginsert simpul level per level sebagai berikut :
LastKiri
Root
Q
A
A
Current
Current
P
F
E
LastKiri
I
J
K
D
G
Q
H
C
B
C
B
D
Root
L
H
F
E
I
J
K
P
G
L
Gambar-6.24 b
Gambar-6.24 a
Pertama kali pointer Q dan LastKiri ditempatkan menunjuk simpul Akar (Gambar-6-24 a). Pointer Q akan mengunjungi simpul satu persatu mulai simpul A,
B, C, D dan seterusnya dengan instruksi Q = Q->LEFT untuk turun ke level berikutnya, dan kemudian Q= Q->LINK untuk berjalan ke kanan sampai Q>LINK == NULL.
Fungsi untuk membaca simpul level per level
void BacaPerLevel()
void BacaPerLevel()
{ Q = Root;
{ Q = Root;
LastKiri = Root;
LastKiri = Root;
printf("%c ", Q->INFO );
printf("%c ", Q->INFO );
while(Q->Left != NULL)
while(Q->Left != NULL)
{ Q = Q->Left;
{ printf("\n");
LastKiri = LastKiri->Left;
Q = Q->Left;
printf("%c ",Q->INFO);
LastKiri = LastKiri->Left;
while(Q->Link != NULL)
printf("%c ",Q->INFO);
{ Q = Q->Link;
while(Q->Link != NULL)
printf("%c ",Q->INFO);
{ Q = Q->Link;
}
printf("%c ",Q->INFO);
Program-1
Q = LastKiri;
Program-2}
A
}
Q = LastKiri;
Bila pohon seperti Gambar-6.24 a
}
}
B
C
atau Gambar-6.24 b, dicetak :
Catatan :
}
Program
diatas
tidak
bisa
D
E
F
G
digunakan untuk mencetak pohon
Dengan : Program-1 akan mencetak :
J
K
M
H
yang no. simpulnya tidak urut
A B C D E F G H I J K L
seperti Gambar-6.25
V
W
Dengan :Program-2
akan mencetak : A
Gambar-6.25
B C
D E F G
H I J K L
220
Bentuk Program selengkapnya.
Membaca pohon biner level per level
Bila Program ini dijalankan, maka akan
terbentuk pohon seperti yang diilustrasikan
pada Gambar-6.26
//Membuat pohon dengan insert level per level
#include<stdio.h> #include<stdlib.h>
#include<conio.h> #include<ctype.h>
#include<math.h>
struct Node
{ struct Node *Left;
char INFO;
struct Node *Right;
struct Node *Link;
};
typedef struct Node Simpul;
Simpul *P,*Q, *Root,
Simpul *LastCurrent, *Current, *LastKiri ;
Semua variabel, dibuat dan digunakan secara
bersifat Global
Untuk memudahkan pengetesan program, data yang akan
diisikan ke simpul pohon, disiapkan berupa array
sehingga tidak perlu diketik setiap kali melakukan
pengetesan. Jumlah data dapat ditambah atau dikurangi
sesuai keperluan
const kiri = 0, kanan = 1;
int i, n, Flag, FlagHabis, Level;
char X, A[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
void
{
}
void
{
}
void
{
}
void
{
}
Lengkapi semua fungsi sesuai dengan yang telah diuraikan
sebelumnya
Inisialisasi ()
BuatSimpul(char X)
Kalau program ini dijalankan (setelah melengkapi fungsi-fungsi yang
diperlukan), maka dalam memory akan terbentuk pohon biner sebagai
berikut :
A
B
BuatSimpulAkar( )
C
D
InsertSimpulPerLevel()
H
P
I
Q
void BacaPerLevel()
{
}
int main()
{
clrscr();
i=0;
X=A[i];
Inisialisasi();
BuatSimpul(X);
BuatSimpulAkar(X);
E
R
F
J
S
T
K
U
V
G
L
W
X
M
Y
N
O
Z
Gambar-6.26
Tentu saja pohon ini tidak terlihat atau tergambar di layar, karena
pohon adanya di dalam memory komputer, dalam bentuk Linked-List.
221
Setelah dicetak dengan fungsi BacaPerLevel( ), maka yang tercetak dan
terlihat dilayar adalah :
A
B C
D E F G
H I J K L M N O
P Q R S T U V W X Y Z
6.10.2 Membaca atau mencari sebuah simpul dengan nomor tertentu.
Contoh-1:
Sudah ada sebuah pohon biner. Strujtur simpul sama seperti yang dicontohkan dalam bab ini. Jumlah simpul dan kedalaman pohon tidak
diketahui. Simpul akar ditunjuk oleh pointer Root. Sudah tersedia pointer P, Q, dan R yang dapat menunjuk alamat sebuah simpul, dapat
digunakan bila diperlukan. Susun algoritma untuk : Memeriksa apakah simpul dengan nomor 50 ada terdapat dalam pohon tersebut. Bila
ada, cetak perkataan “ADA’”, bila tidak ada, cetak perkataan “TIDAK ADA”.
Jawab :
Program terdiri dari 2 tahap.
Tahap-1 :
Menentukan alur pencarian untuk menuju simpul no 50.
Alurnya adalah :
Root
kanan - kiri – kiri - kanan – kiri
(lihat Gambar- a)
12
Bila kanan dinyatakan dengan 1, dan kiri dengan 0,
maka alurnya menjadi :
1–0–0–1–0
Tahap-2 :
A
1
L
0
1
F
6
1
Y
0
50
C
0
3
Q
4
25
3
a
1
0
0
1
0
2
1
0
Top
S
Gambar- b
Gambar- a
Berdasarkan nilai yang ada dalam Stack. S, pohon ditelusuri mulai dari simpul akar. Bila simpul no 50 ada, maka
Dan
nilai sebaliknya
tersebut cetak
kedalam
Stack “TIDAK
S.
cetakmenyimpan
perkataan “ADA,
perkataan
ADA”.
(lihat Gambar b)
// Tahap-1.
n = 50; Top = -1;
hasil = n;
while(hasil > 1)
{ sisa = n % 2; n = n/2;
hasil = n;
Top++; S[Top] = sisa;
// }
Tahap-2.
Q = Root;
while(Top >= 0 && Q != NULL)
{ arah = S[Top]; Top--;
if(arah == 0 )
Q = Q->Left;
else
Q = Q->Right;
}
if (Q != NULL)
printf(“ADA”);
Else
printf(“TIDAK ADA”);
Bagi terus menerus 50 dengan 2.
Sisa pembagian simpan di Stack S.
Proses selesai bila hasil sudah = 1.
50
25
12
6
3
/
/
/
/
/
2
2
2
2
2
= 25 sisa = 0
= 12
1
= 6
0
= 3
0 hasil
= 1
1
Keluar dari Loop bila :
Top == -1 atau Q == NULL.
Bila Q == NULL berarti, simpul no 50, atau no. 25, atau
no. 12 , atau no. 6 atau no. 3, atau no. 1 tidak ada.
222
6.11 Penelusuran Pohon Biner.
Penelusuran (traverse atau traversal ) pohon biner, maksudnya membaca atau mengunjungi (visit) simpul-simpul pohon biner dengan
urutan tertentu. Ada 3 (tiga) macam penelusuran, yang bila ditambah dengan kebalikannya menjadi 6 (enam) macam penelusuran sebagai
berikut :
1. Preorder (atau depth-first order)
4. Inverse Preorder
2. Inorder (atau symetric order)
5. Inverse Inorder
3.
Postorder
6. Inverse
Untuk memahami istilah Pre, Post, In, order diatas, pandanglah
sebuah Postorder
pohon atau subpohon sebagai berikut :
+
A
Pohon pada Gambar-6.27 a
B
Bila ditelusuri secara
maka hasil penelusurannya:
Preorder
+ A B (bentuk PREFIX)
Inorder
A + B (bentuk INFIX)
Postorder
A B + (bentuk POSTFIX)
Pohon pada Gambar-6.27 a diatas, sebenarnya adalah hasil representasi arithmatic statement : A + B
ke dalam pohon biner. Dalam
arithmetic statement A + B,
A dan B disebut operand dan tanda tambah (+) disebut operator. Bentuk A + B ini biasa disebut bentuk
INFIX, yang artinya operatornya berada didalam (IN). Selain bentuk INFIX, komputer mengenal bentuk PREFIX seperti + A B, dimana
operatornya berada sebelum (PRE) dua buah operand, dan bentuk POSTFIX seperti A B + dimana operatornya berada sesudah (POST)
dua buah operand.
Tapi sebuah pohon biner belum tentu merupakan representasi arithmetic statement, seperti yang diilustrasikan paga Gambar-6-27 b
Gambar-6.27 a
A
B
Pohon pada Gambar-6.27 b
C
Bila ditelusuri secara
Preorder
Inorder
Postorder
Dari dua ilustrasi diatas, dapat dilihat sebagai berikut:
maka hasil penelusurannya:
A
B
B
Gambar-6.27 b
B
A
C
C
C
A
Karena bukan merupakan arithmetic
statement, jadi tidak diistilahkan
dengan bentuk INFIX, PREFIX dan
POSTFIX
Untuk penelusuran Preorder, urutannya adalah : Ambil Akar, kemudian telusuri secara preorder subpohon kiri, dan setelah selesai
penelusuran ke subpohon kiri, kemudian dilanjutkan dengan penelusuran secara preorder ke subpohon kanan. Jadi penelusurannya
sendiri bersifat recursive.
Dalam buku literatur, untuk penelusursn preorder ditulis :
1. Visit the root.
2. Traverse the left subtree in preorder.
3. Traverse the right subtree in preorder
223
Untuk penelusuran inorder :
1. Traverse the left subtree in preorder.
2. Visit the root.
3. Traverse the right subtree in preorder
Untuk penelusuran Postorder
1. Traverse the left subtree in postorder
2. Traverse the right subtree in postorder
3. Visit the root.
Agar mudah diingat, prosesnya ketiganya dapat disingkat sebagai berikut :
Untuk Preorder, ---> AKAR, KIRI, KANAN
Untuk Inorder, ----> KIRI, AKAR, KANAN
Untuk Postorder, --> KIRI, KANAN, AKAR
6.11.1 Beberapa contoh pohon biner dan hasil penelusurannya :
A
A
A
B
Gambar-6.28 a
B
B
C
Preorder : A B
Inorder : B A
Postorder: B A
A
H
E
J
F
K
H
G
E
J
F
K
V
M
G
M
W
Gambar-6.28 f
Gambar-6.28 e
Pre : A B D H E J K V W C F M G
In : H D B J E V K W A F M C G
Post: H D J V W K E B M F G C A
Pre : A B D H E J K C F M G
In : H D B J E K A F M C G
Post: H D J K E B M F G C A
Lihat Gambar-6.28 f
Untuk Preorder : Akar, Kiri, Kanan :
A
Akar
C
D
C
F
Pre : A B D E C F
In : D B E A F C
Post: D E B F C A
B
B
D
E
Gambar-6.28d
Preorder : A B C
Inorder : B A C
Postorder: B C A
A
C
D
Gambar-6.28c
Gambar-6.28 b
Preorder : A
Inorder : A
Postorder: A
A
E
B
D H
Akar
Kiri
Akar
J
Kiri
Kanan
K V W
C
F M
Akar
Kiri
Kanan
Kiri
Kanan
Sehingga didapat hasil penelusuran preorder : A B D H E J K V W C F M G
224
G
Kanan
Gambar-6.28 f digambarkan ulang
A
B
C
D
E
J
H
F
K
V
Hasil penelusuran
G
M
Pre : A B D H E J K V W C F M G
In : H D B J E V K W A F M C G
Post: H D J V W K E B M F G C A
Gambar-6.28 f
W
Lihat Gambar-6.28f
Untuk Inorder : Kiri, Akar, Kanan :
J
H D
B
Kiri
Akar
V K W
E
Kiri
Akar
Kanan
Kanan
A
Akar
Kiri
F M
C
Kiri
Akar
G
Kanan
Kanan
Sehingga didapat hasil penelusuran inorder : H D B J E V K W
A
F M C G
Lihat Gambar-6.28 f
Untuk Postorder : Kiri, Kanan, Akar :
H D
J
V W K
E
Kiri
Kanan
Kanan
Akar
Kiri
B
M F
Akar
Kiri
G
C
Kanan
Kiri
Akar
A
Akar
Kanan
Sehingga didapat hasil penelusuran postorder : H D J V W K E B
M F G C
A
A
B
C
D
E
H
P
I
Q
R
F
J
S
T
K
U
V
G
L
W
X
M
Y
Z
Hasil penelusuran untuk pohon Gambar-6.29
Preorder : A
B D HPQ IRS E JTU KVW
C
F LXY MZ
Inorder : PHQ D RIS B TJU E VKW
A
XLY F ZM C
Postorder: PQH RSI D TUJ VWK E B
XYL ZM F NOG C
225
GNO
NGO
A
N
Gambar-6.29
O
6.11.2 Program (Fungsi) Penelusuran Pohon Biner
Hanya ada 3 (tiga) macam penelusuran yang akan dibahas, yaitu Preorder, Inorder, dan Postorder. Algoritma
penelusuran ditulis dalam sebuah fungsi. Fungsi dapat bersifat recursive atau non recursive.
1) Fungsi yang bersifat recursive
a. Fungsi Penelusuran Preorder. Ingat : Akar, Kiri, Kanan
void PreOrder(Simpul *T)
{ if(T != NULL)
{ printf("%c ", T->INFO);
PreOrder(T->Left);
PreOrder(T->Right);
}
} Penelusuran Inorder. Ingat : Kiri, Akar, Kanan
b. Fungsi
void InOrder(Simpul *T)
{ if(T != NULL)
{ InOrder(T->Left);
printf("%c ", T->INFO);
InOrder(T->Right);
}
}
c. Fungsi Penelusuran
Postorder. Ingat : Kiri, Kanan, Akar.
Fungsi ini akan dipanggil dari program induk atau fungsi
main( ) dengan instruksi :
Preorder(Root);
Fungsi ini akan dipanggil dari program induk atau fungsi
main() dengan instruksi :
Inorder(Root);
void PostOrder(Simpul *T)
Fungsi ini akan dipanggil dari program induk atau fungsi
{ if(T != NULL)
main() dengan instruksi :
{ PostOrder(T->Left);
PostOrder(T->Right);
Postorder(Root);
printf("%c ", T->INFO);
}
Perhatikan :
}
1.
Walaupun diusahakan selalu menggunakan variabel Global, agar mudah dipahami, namun ketiga fungsi diatas, semuanya
menggunakan variabel Lokal T. Hal ini tidak dapat dihindari karena fungsi bersifat recursive.
2. Setiap simpul yang dikunjungi, nilai INFOnya selalu dicetak agar terlihat dilayar urutan simpul yang dikunjungi.
Gunakan ketiga fungsi diatas, sebagai pengganti fungsi BacaPerLevel( ), pada program yang dicontohkan sebelumnya maka akan
terlihat hasil penelusuran pohon Gambar-6.25 sebagai berikut :
Preorder : A B D H P Q I R S E J T U K V W C F L X Y M Z G N O
Inorder : P H Q D R I S B T J U E V K W A X L Y F Z M C N G O
Postorder: P Q H R S I D T U J V W K E B X Y L Z M F N O G C A
226
2) Fungsi yang bersifat non recursive
Proses disini menggunakan Stack, untuk menyimpan alamat simpul simpul yang telah dikunjunggi. Alamat ini penting untuk
disimpan agar dapat kembali menuju Akar atau simpul yang ada di ‘atas’ nya. Besarnya Stack tergantung kebutuhan yang lebih
dikaitkan dengan ketinggian atau kedalaman pohon. Karena digunakan untuk menyimpan alamat, maka tipe Stack adalah tipe pointer
(menggunakan bintang (*) ) yakni pointer yang menunjuk suatu Simpul.
a. Fungsi untuk Penelusuran Preorder non recursive.
b.
void PreOrderNonRec(Simpul *T)
{ int top, X;
Simpul *S[20];
Simpul *P;
top = -1;
P = T;
do
{ while(P != NULL)
{ X = P->INFO;
printf(“%c “, X);
top++; S[top] = P;
P = P->Left;
}
if(top > -1)
{ P = S[top]; top --;
P = P->Right;
} Inorder non recursive.
Fungsi Penelusuran
}
> -1) || (P
!= NULL));
void while((top
InOrderNonRec(Simpul
*T)
} int top, X;
{
Simpul *S[20];
Simpul *P;
top = -1;
P = T;
do
{ while(P != NULL)
{ top++; S[top] = P;
P = P->Left;
}
if(top > -1)
{ P = S[top]; top --;
X = P->INFO;
printf(“%c “, X);
P = P->Right;
}
}
while((top > -1) || (P != NULL));
Fungsi ini akan dipanggil dari program induk
atau fungsi main( ) dengan instruksi :
PreOrderNonRec(Root);
Perhatikan instruksi : Simpul *S[20]
Instruksi ini menyiapkan array satu dimensi bernama
S sebanyak 20 elemen bertipe pointer (pakai *)
dimana pointer tersebut dapat mencatat alamat obyek
berstruktur Simpul.
Fungsi ini akan dipanggil dari program induk
atau fungsi main( ) dengan instruksi :
InOrderNonRec(Root);
227
6.12 Pohon Biner Berbenang (Threaded Binary Tree).
Pohon biner berbenang (threaded binary tree) adalah pohon biner dimana semua pointer yang bernilai NULL dibuat menjadi benang
(thread). Untuk pohon biner dengan jumlah simpul = n, maka akan terdapat pointer benang sebanyak 2n. Jumlah pointer yang bernilai null
ada sebanyak n+1, lebih banyak dari pointer yang bukan null (busur) yang jumlahnya = n-1. Untuk pohon biner, semua simpul daun akan
mempunyai dua buah benang, benang-kiri dan benang kanan, sedangkan simpul lain mungkin mempunyai salah satu benang, benang-kiri
atau benang-kanan, dan sebagian simpul tidak mempunyai benang.
Pointer null dibuat menjadi benang karena memang ada gunanya. Benang digunakan untuk menujuk simpul ‘diatas’nya dalam urutan
penelusuran inorder.
Perhatikan pohon biner berbenang pada Gambar-6-30 berikut ini, dimana benang digambarkan dengan garis putus-putus tipis.
Head
Root
Catatan :
Pengertian simpul successor menurut
urutan Inorder, dapat diterangkan
menggunakan Gambar-6.30.
A
B
D
E
H
I
R
Bila berada di simpul R, maka successor
inorder adalah simpul I.
C
F
K
J
S
G
Bila berada di simpul I, maka successor
inorder adalah simpul S.
Bila berada di simpul S, maka successor
inorder adalah simpul B
Gambar-6.30
Perhatikan aturan pembuatan benang setiap simpul. Untuk keperluan pemrograman, maka dibuatkan sebuah simpul Kepala yang
ditunjuk oleh pointer Head. Head->Left dibuat menunjuk akar, sedangkan Head->Right menunjuk simpul Kepala itu sendiri.. Ada dua
benang yang khusus menuju ke simpul kepala yanitu benang-kiri simpul paling kiri, dan benang-kanan simpul paling kanan. Bila simpul
kepala tidak ada, maka kedua benang ini menunjuk ke simpul akar.
Pohon biner pada Gambar-6-30 diatas, bila ditelusuri secara INORDER, maka urutannya adalah :
H D R I S B J E A K F C G
Pandanglah urutan penelusuran Inorder dari H ke D, atau dari R ke I atau dari S ke B, semuanya dapat dilakukan dengan cepat melalui
benang-kanan, tanpa harus melakukan proses secara recursive. Jadi kalau hanya untuk keperluan penelusuran inorder, yang diperlukan
hanyalah benang-kanan. Atau dengan perkataan lain, setiap simpul yang mempunyai benang-kanan berarti benang tersebut adalah
merupakan jalur untuk penelusuran inorder untuk mencapai akar.
228
6.12.1 Struktur Pohon Biner Berbenang
Sekarang timbul persoalan, bagaimana membedakan pointer yang keluar dari sebuah simpul, apakah berfungsi sebagai busur
penghubung dua buah simpul, atau berfungsi sebagai benang. Untuk itu dibuat dua buah elemen dalam simpul tersebut yang isinya berupa
tanda atau yang dalam pemrograman biasa disebut flag. Sebut saja namanya FlagKiri dan FlagKanan. Bila FlagKiri berisi 0 (nol) maka
pointer-kiri (Left) berfungsi sebagai busur atau null, tapi bila isinya = 1 (satu) maka pointer-kiri berfungsi sebagai benang. Demikian juga
dengan FlagKanan untuk pointer-kanan Dalam bahas C/C++, struktur simpulnya dapat ditulis sebagai berikut :
Struktur Simpul Pohon biner berbenang.
struct Node
{
char INFO;
int FlagKiri, FlagKanan;
struct Node *Right
struct Node *Left;
};
typedef struct Node Simpul;
INFO
void BuatSimpul( char X)
{P = (Simpul*) malloc
Flag
Flag
(sizeof(Simpul));
Kiri
Kanan
if(P != NULL)
{ P->INFO = X;
P->Left = NULL;
Left
Right
P->Right = NULL;
P->FlagKiri = 0;
Dan setiap kali pembuatan sebuah simpul baru,
P->FlagKanan = 0; }
Bila simpul baru tersebut ditunjuk oleh pointer P, maka perlu
else
ditambahkan instruksi :
{ printf(“Memory
P->FlagKiri = 0;
P->FlagKanan = 0;
Heap Full”);
exit(1);
Seperti yang dicontohkan diatas.
}
Dengan demikian pohon biner berbenang yang digambarkan pada Gambar 6-30 dapat digambarkan
lebih jelas dengan Gambar-6.31
}
sebagai berikut.
Head
Root
0
0
0
0
1
H
D
B
0
0
0
1
R
1
I
0
1
1
S
0
0
0
1
A
H
D
1
1
0
1
1
Gambar-6.31
229
F
1
F
1
C
0
1
C
1
0
6.12.2 Penelusuran INORDER Pohon Biner Berbenang
Dengan memanfaatkan benang-kanan untuk kembali ke simpul succesor secara inorder, maka penelusuran secara INORDER non
recursive dapat dibuat tanpa menggunakan Stack sebagai berikut :
Prosedur Penelusuran INORDER non recursive,
T = Head
pada pohon biner berbenang
h
0 0
void InOrderBenang(Simpul *T)
{ Simpul *Q, *R;
A
Q = T;
0 0
do
{ R = Q->Right;
C
B
if(Q->FlagKanan == 0)
0 1
0 0
{ while(R->FlagKiri == 0)
F
{ R = R->Left; }
D
E
1 1
1 1
0 0
}
Q = R;
G
H
1 1
1 1
if(Q != T)
Gambar-6.32
printf("%c ", Q->INFO);
Procedeure
ini dipanggil dari program utama dengan instruksi InOrderBenang(Head); Bila Pohon pada Gambar-6.32
}
ditelusuri
dengan
prosedur ini akan menghasilkan cetakan :
while(Q
!= T);
}
D
B
G adalah
E
H
A yang
F dibuat
C secara
yaitu hasil
penelusuran
Inorder.
Pohon Gambar-6.28
pohon
sembarang,
tanpasecara
aturan
tertentu. Cara membuatnya hanya dengan
instruksi-instruksi dasar sebagai berikut :
Penggalan program membuat Pohon Biner Berbenang sembarang seperti Gambar-6.32
BuatSimpul('A');
BuatSimpul('h');
BuatSimpul('B');
BuatSimpul('C');
BuatSimpul('D');
BuatSimpul('E');
BuatSimpul('F');
BuatSimpul('G');
BuatSimpul('H');
BuatSimpulAkar();
BuatSimpulHead();
Akar->Left = P;
Akar->Right = P;
P->Right = Head; P->FlagKanan = 1;
Akar->Left->Left = P;
P->Left = Head; P->FlagKiri = 1;
P->Right = Akar->Left; P->FlagKanan = 1;
Akar->Left->Right = P; Q = P;
Akar->Right->Left = P;
P->Left = Akar; P->Right = Akar->Right;
P->FlagKiri = 1; P->FlagKanan = 1;
Q->Left = P;
P->Left = Akar->Left; P->Right = Q;
P->FlagKiri = 1; P->FlagKanan = 1;
230
Q->Right = P;
Pembuatan pohon dila-kukan
secara ‘manual’ , satu per satu
hanya untuk digunakan seba-gai
contoh. Tentu saja pembuatan
sebenarnya secara terprogram,
sa-ma dengan pembuatan pohon
level
per
level
dengan
menambahkan benang.
6.13. Contoh Program
16.13.1 Program membuat pohon biner dengan insert level per level
//Membuat dan menelusuri pohon biner dengan insert level per level
//atree05.cpp
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<ctype.h>
#include<math.h>
struct Node
{ struct Node *Left;
char INFO;
struct Node *Right;
struct Node *Link;
};
typedef struct Node Simpul;
Simpul *P,*Q, *Akar, *LastCurrent, *Current, *LastKiri ;
const int kiri = 0, kanan = 1;
int i, n, Flag, FlagHabis, Level;
char X, A[35] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678";
P
0
1
kiri
kanan
Simpul baru dibuat
INFO
void Inisialisasi ()
{ Akar = NULL;
Link
}
Left Right
void BuatSimpul(char item)
{ P = (Simpul*) malloc(sizeof(Simpul));
kiri
if(P !=NULL)
LastKiri
{ P->INFO = item;
Flag
LastCurrent
P->Left = NULL;
0
Akar
P->Right = NULL;
P
Level
INFO
P->Link = NULL;
1
}
n
Link
else
1
{ printf("Memory Penuh");
Left Right
FlagHabis
exit(1);
Simpul yang baru dibuat dijadikan
}
sebagai simpul Akar
}
void BuatSimpulAkar( )
Program bersambug ke-halam berikutnya
{ if(Akar == NULL)
Flag= =P;
kiri, kalau ada insert, akan diinsert di bagian kiri
Catatan :{ Akar
LastCurrent = Akar;
FlagHabis= =Akar;
1, jumlah simpul pada level tersebut sudah habis, kalau ada insert, dilanjutkan ke level berikutnya, dan kemudian
LastKiri
FlagHabis dibuat = 0.
Flag
= kiri;
Level
= 0;
n = 1, jumlah simpul ,
Level = 0 sekarang sedang ada di level 0
n = 1;
FlagHabis = 1;
231
}
void TambahSimpul()
{if(Akar != NULL)
{ n=n+1;
if(FlagHabis == 1)
{ FlagHabis = 0;
Current = P;
LastCurrent->Left = P;
Flag = kanan;
Level = Level + 1;
}
else
{if(Flag == kiri)
{ Flag = kanan;
LastCurrent->Left = P;
Current->Link = P;
Current = P;
}
else
{LastCurrent->Right = P;
Current->Link = P;
Flag = kiri;
if( n == (pow(2,Level+1)- 1))
{ FlagHabis = 1;
LastCurrent = LastKiri->Left;
LastKiri = LastKiri->Left;
}
else
{Current->Link = P;
Current = P;
LastCurrent = LastCurrent->Link;
}
}
}
}
else
printf(“Pohon Belum Ada ");
}
void PreOrder(Simpul *T)
{ if(T != NULL)
{ printf("%c ", T->INFO);
PreOrder(T->Left);
Akar
1
1
FlagHabis
2
Menginsert simpul paling
kiri dalam suatu level,
misal simpul no-2, atau
no-4, atau no-8
3
5
4
8
9
10
11
12
6
13
7
14
15
Menginsert simpul sebelah kiri, tapi bukan yang
paling kiri, misal simpul no-6, atau no-10, atau
no-12, atau no-14
Menginsert simpul sebelah kanan, termasuk yang paling kanan,
seperti simpul no-3, atau no-5 atau no-7, atau no-9, atau no-11
dan seterusnya.
Bila yang diinsert adalah simpul yang paling kanan dari suatu level,
maka : FlagHabis dibuat = 1, dan LastCurrent dibuat menunjuk
simpul paling kiri pada level tersebut.
LastKiri
LastCurrent
Root
P
Current
A
1
Link
n = 2
level = 1
2
FlagHabis = 0
Flag = kanan
Keadaan setelah insert Simpul
no-2
B
LastCurrent
LastKiri
Current
n = 3
FlagHabis = 1
Flag = kiri
level = 2
Root
1
A
P
B
2
C
3
Keadaan setelah insert Simpul
no-3
232
void PostOrder(Simpul *T)
{ if(T != NULL)
{ PostOrder(T->Left);
Root
LastCurrent
LastKiri
PostOrder(T->Right);
printf("%c ", T->INFO);
}
}
P
void BacaPerLevel()
A
B
Current
C
D
n = 4
FlagHabis = 0
Flag = kanan
level Simpul
= 2
Keadaan setelah insert
no-4
{ Q = Akar;
LastKiri = Akar;
printf("%c ", Q->INFO );
while(Q->Left != NULL)
{ printf("\n");
Q = Q->Left;
Root
LastKiri = LastKiri->Left;
A
LastKiri
printf("%c ",Q->INFO);
LastCurrent
while(Q->Link != NULL)
B
{ Q = Q->Link;
printf("%c ", Q->INFO );
Current
D
}
Q = LastKiri;
C
P
E
Keadaan setelah insert Simpul
no-5
}
}
int main()
Root
{ clrscr();
A
LastKiri
i=0;
LastCurrent
X=A[i];
C
B
Inisialisasi();
P
BuatSimpul(X);
BuatSimpulAkar(X);
D
E
Current
F
for(i=1; i<=25; i++)
{ X=A[i];
Keadaan setelah insert Simpul
no-7
BuatSimpul(X);
TambahSimpul();
}
PreOrder(Akar);
233
6.13.2 Program membuat pohon biner berbenang
//Membuat dan menelusuri pohon biner berbenang
//Benang.cpp
#include<stdio.h>
#include<conio.h>
#include<math.h>
struct Node
{ char INFO;
int FlagKiri, FlagKanan;
struct Node *Right;
struct Node *Left;
};
typedef struct Node Simpul;
Simpul *P,*Q, *Akar, *Head;
INFO
Flag
Kiri
Left
void Inisialisasi ()
{ Akar = NULL;
Head = NULL;
}
Right
X
0
void BuatSimpul(char X)
{ P = (Simpul*) malloc(sizeof(Simpul));
if(P !=NULL)
{ P->INFO = X;
P->Left = NULL;
P->Right = NULL;
P->FlagKiri = 0; P->FlagKanan = 0;
}
else { printf("Memory Penuh");
exit(1);
}
}
0
Head
0
Akar
A
0 0
C
0 1
B
0 0
void BuatSimpulAkar( )
{ if(Akar == NULL)
{ Akar = P;
Akar->INFO = 'A';
}
else
{ printf("Akar Sudah ada");
exit(1);
}
}
void BuatSimpulHead( )
{
Flag
Kanan
D
1 1
F
1 1
E
0 0
G
1 1
H
1 1
Gambar-6.33
234
h
0
T = Head
void InOrderBenang(Simpul *T)
{ Simpul *Q, *R;
0
Q = T;
do
if(Q->FlagKanan == 0)
}
C
0 1
B
0 0
while(R->FlagKiri == 0)
{ R = R->Left; }
0
A
0 0
{ R = Q->Right;
{
h
D
1 1
Q = R;
if(Q != T)
printf("%c ", Q->INFO);
}
F
1 1
E
0 0
G
1 1
H
1 1
Gambar-6.34
while(Q != T);
}
int main()
{ clrscr();
Inisialisasi();
BuatSimpul('A'); BuatSimpulAkar();
BuatSimpul('h'); BuatSimpulHead();
BuatSimpul('B'); Akar->Left = P;
BuatSimpul('C'); Akar->Right = P;
P->Right = Head; P->FlagKanan = 1;
BuatSimpul('D'); Akar->Left->Left = P;
P->Left = Head; P->FlagKiri = 1;
P->Right = Akar->Left; P->FlagKanan = 1;
BuatSimpul('E'); Akar->Left->Right = P; Q = P;
BuatSimpul('F'); Akar->Right->Left = P;
P->Left = Akar; P->Right = Akar->Right;
P->FlagKiri = 1; P->FlagKanan = 1;
BuatSimpul('G'); Q->Left = P;
P->Left = Akar->Left; P->Right = Q;
P->FlagKiri = 1; P->FlagKanan = 1;
BuatSimpul('H'); Q->Right = P;
235
P->Left = Q; P->Right = Akar;
Catatan :
Pembuatan
simpul-simpul
dilakukan secara manual untuk
memudahkan pem-buatan contoh.
6.14. Soal-Soal Latihan Mandiri.
Untuk semua soal yang berkaitan dengan algoritma, maka dinyatakan bahwa simpul akar pohon biner yang dijadikan soal, telah ditunjuk oleh
pointer Root.
1.
2.
Sebuah pohon biner kedalamnya = 10.
Ditanya :
a. Jumlah maksimum simpul pada level 10.
b. Jumlah minimum simpul pada level 10.
c. Jumlah maksimum seluruh simpul
d. Jumlah minimum seluruh simpul
Sebuah pohon biner mempunyai jumlah simpul = 125.
Ditanya :
A
B
C
D
E
G
a. Kedalaman maksimum pohon tersebut.
b. Kedalaman minimum pohon tersebut.
F
H
Gambar-6.34
3.
Perhatikan pohon biner Gambar-6.34 diatas. Sebutkan nomor simpul yang isi INFOnya adalah huruf
4.
Simpan pohon biner Gambar-6.34 diatas ke dalam array satu dimensi.
5.
Diketahui sebuah array satu dimensi yang dibuat dengan char A[15]; Sudah ada isinya sebagai berikut :
0
1
2
A
3
B
4
5
C
6
7
D
8
9
E
I
10
11
12
13
“ I ”.
14
F
G
Gambarkan Pohon Biner-nya bila array satu dimensi diatas direpresentasikan kedalam sebuah pohon biner tersbut
6.
Sebuah pohon biner kedalamanya = 7. Berapa paling sedikit elemen array yang perlu disiapkan agar dapat menampung isi pohon
biner tersebut.
7.
Pada sebuah pohon biner. Bila kita bergerak mulai dari simpul Akar dengan arah gerakan sebagai berikut :
kanan, kiri, kanan, kiri, kiri
Maka kita akan sampai pada simpul nomor berapa ?
8.
Pada sebuah pohon biner. Sebutkan arah gerakan (kiri / kanan) bila bergerak mulai
dari simpul Akar menuju simpul no. 100.
9.
Tuliskan hasil penelusuran pohon biner pada Gambar-6.35 bila ditelusuri atau
dibaca dengan cara :
a. Penelusuran Level per level
b. Penelusuran inorder
c. Penelusuran preorder
d. Penelusuran postorder
236
Root
A
B
D
C
E
H
G
F
I
Gambar-6.35
10.
11.
Tuliskan penggalan program (atau fungsi) untuk membaca atau menelusuri sebuah pohon biner tanpa proses recursive bila
ditelusuri secara :
a. Level per level
b. inorder
c. preorder
Sebuah pohon biner, field INFOnya bertipe integer. Tuliskan penggalan program (atau fungsi) untuk mencetak TOTAL isi INFO.
12.
Tuliskan penggalan program (atau fungsi) untuk mencetak JUMLAH simpul sebuah pohon biner.
13.
Sauatu pohon biner, INFOnya bertipe int. Tuliskan penggalan program (atau fungsi) untuk mencetak nilai INFO yang terbesar.
14.
Sauatu pohon biner, INFOnya bertipe int. Tuliskan penggalan program (atau fungsi) untuk mencetak nilai INFO simpul yang
berada pada ujung paling kanan.
15.
Tuliskan penggalan program (atau fungsi) untuk mencetak nomor simpul yang paling besar (paling tinggi).
16.
Tuliskan penggalan program (atau fungsi) untuk mencetak kedalaman sebuah pohon biner.
17
Ada banyak pohon biner yang bila ditelusuri dengan cara preorder, hasilnya
sebagai berikut :
Root
A
ABCDEFGH
B
Gambarkan pohon biner tersebut yang :
Mempunyai kedalam minimum.
Mempunyai kedalam maximum
18.
D
C
E
H
Gambarkan pohon biner berbenang untuk pohon biner yang digambar pada
Gambar-6.36.
G
F
I
Gambar-6.36
19.
Tuliskan penggalan program (atau fungsi) untuk memeriksa apakah simpul no 100 ada dalam sebuah pohon biner. Bila ada cetak
perkataan “ADA”, sebaliknya cetak perkataan “TIDAK ADA”.
20.
Sudah ada sebuah simpul baru yang ditunjuk oleh pointer P. Tuliskan penggalan program (atau fungsi) untuk menginsert simpul
tersebut sebagai simpul no 100, bila dipastikan simpul no 100 belum ada, tapi simpul nomor 50 sudah ada.
21.
Sudah ada sebuah simpul baru yang ditunjuk oleh pointer P. Tuliskan penggalan program (atau fungsi) untuk menginsert simpul
tersebut sebagai simpul no 100, bilamana memungkinkan. Bila tidak mungkin dapat diinsert, maka cetak perkataan “TIDAK
DAPAT DIINSERT”. Tidak dapat diinsert bila simpul superordinat dari simpul nomor 100 tidak ada, atau simpul nomor 100 itu
sendiri sudah ada.
237
22.
Sudah ada pohon biner seperti yang diilustrasikan pada Gambar-6-37. Susun
algoritma untuk membaca dan mencetak isi seluruh simpul sehingga tercetak
sebagai berikut :
A
B
C
23.
D
H
E
J
K
F
B
C
D
V
W
E
J
H
F
V
Susun algoritma untuk membuat pohon biner untuk menyimpan
G
kalimat :
“JAKARTA RAYA INDONESIA“
sehingga terrbuat pohon seperti Gambar-6-38.
A
M
W
Gambar-6-37
J
K
R
R
D
O
T
A
N
E
G
K
H
A
24.
A
Y
S
I
A
A
I
A
N
Gambar-6.38
Sudah ada pohon biner INFOnya bertipe char. Susun algoritma untuk mencetak INFO seluruh simpul daun. Bila pohonnya seperti
pada Gambar 6-37 diatas, maka seharusnya tercetak :
H J V W M G
25.
Sudah ada dua buah pohon biner. Akar pohon biner pertama ditunjuk oleh pointer Root1. Akar pohon biner kedua ditunjuk oleh
pointer Root2. Susun program untuk memeriksa apakah pohon biner pertama tepat sama dengan pohon biner kedua. Yang
dimaksud dengan tepat sama disini adalah jumlah dan tata letak simpulnya sama, bukan isi INFOnya. Bila tepat sama cetak
perkataan “SAMA”, sebaliknya cetak perkataan “TIDAK SAMA “.
Pohon pada Gambar-6-39 , tepat sama dengan pohon pada Gambar 6-40, walaupun isinya tidak sama, tapi jumlah
Ilustrasi :
simpul dan tata letak simpul sama. Sedangkan pohon pada Gambar-6.39 tidak “tepat sama “ dengan pohon pada
Gambar-6.41
A
P
B
C
D
H
E
J
F
K
Gambar-6.39
Q
G
M
A
R
S
W
T
X
U
Y
Gambar-6.40
238
B
V
Z
C
D
E
F
J
Gambar-6.41
G
M