Vous êtes sur la page 1sur 8

package AVLtree.

modul;
class Node {
int data;
int tinggi; //tinggi node
Node pKiri;//pointer cabang kiri
Node pKanan;//pointer cabang kanan
Node pInduk;// pointer ke induk
//constructor node
public Node(int dt, int tg, Node pKi, Node pKa, Node pI) {
this.data = dt;//inisialisasi variabel
this.tinggi = tg;
this.pKiri = pKi;
this.pKanan = pKa;
this.pInduk = pI;
}
}
public class AVLT {
private Node root;//mendeklarasikan variabel root dari kelas Node
public AVLT() {
root = null;//inisialisasi variabel root
}
//cari dt di tree, mengembalikan true jika ditemukan
//dan false jika tidak
public boolean cariDt(int dt) {
Node temp = root;//temp diinisialisasikan sebagai root
while (temp != null) {//jika temp tidak sama dengan null
if (dt == temp.data) {//jika parameter dt samadengan data pada temp(
root), data ditemukan
return true;//mengembalikan nilai true
} //cariDt subtree pKiri
else if (dt < temp.data) {//jika data lebih kecil dari root
temp = temp.pKiri;//bergeser ke cabang kiri
} //cariDt subtree pKanan
else {
temp = temp.pKanan;//bergeser ke cabang kanan
}
}
//dt tidak ditemukan
return false;
}
//sisip dt ke dalam tree, returns true jika data berhasil disimpan,
// false jika gagal
//menyeimbangkan tree menggunakan algoritma AVL
public boolean sisipDt(int dt) {
if (root == null) {
//sisip dt di root
root = new Node(dt, 1, null, null, null);
return true;
} //tree tidak kosong
else {
//mulai dari root

Node temp = root;//deklarasi variabel temp dari class Node dan inisi
alisasi menjadi root
Node prev = null;//deklarasi variabel prev dari class Node dan inisi
alisasi null
//cari lokasi penyisipan dt
while (temp != null) {
if (dt == temp.data) {//jika data disisipkan samadengan data pad
a temp (root)
return false;//return false
} //sisip dt di subtree pKiri
else if (dt < temp.data) {//jika data lebih kecil dari temp (roo
t)
prev = temp;//data prev diinisialisasikan sebagai temp
temp = temp.pKiri;//bergeser ke cabang kiri
} //sisip dt di subtree pKanan
else {
prev = temp;//data prev diinisialisasikan sebagai temp
temp = temp.pKanan;//bergeser ke cabang kanan
}
}
//buat node baru
temp = new Node(dt, 1, null, null, prev);//membuat object baru dari
class Node dengan inisialisasi parameter
if (dt < prev.data) {//jika dt lebih kecil dari data prev (data sebe
lum dt disispkan)
prev.pKiri = temp;//sisip di pKiri
} else {
prev.pKanan = temp; //sisipDt di pKanan
}//mulai dari node yang disisipkan dan
//bergerak menuju root
rotation(temp);//rekursif method rotasi, dengan parameter temp
return true;//jika penyisipan berhasil
}
}
public void rotation(Node temp) {
while (temp != null) {
//subtree pKiri dan pKanan memenuhi kondisi AVL (seimbang)
if (Math.abs(tinggi(temp.pKiri) - tinggi(temp.pKanan)) <= 1) {
temp.tinggi = Math.max(tinggi(temp.pKiri), tinggi(temp.pKanan))
+ 1;//untuk menghitung tinggi tree
} //kasus 1 algoritma AVL (rotasi kiri), jika tinggi pkiri dan pkana
n berjarak>=2, dan anak dari cabang terakhi pkirir=2
else if (tinggi(temp.pKiri) - tinggi(temp.pKanan) >= 2 && tinggi(tem
p.pKiri.pKiri) >= tinggi(temp.pKiri.pKanan)) {
temp = rotasikiri(temp);//rekursif method rotasikiri dengan para
meter root
//hitung tinggi dari root
temp.tinggi = Math.max(tinggi(temp.pKiri), tinggi(temp.pKanan))
+ 1;
} //case 2 algoritma AVl (rotasi kanan), jika tinggi pkanan dan pkir
i berjarak>=2, dan anak pada cabang terakhir pkanan=2
else if (tinggi(temp.pKanan) - tinggi(temp.pKiri) >= 2 && tinggi(tem
p.pKanan.pKanan) >= tinggi(temp.pKanan.pKiri)) {
temp = rotasikanan(temp);//rekursif method rotasikanan dengan pa
rameter root
//hitung tinggi dari root

temp.tinggi = Math.max(tinggi(temp.pKiri), tinggi(temp.pKanan))


+ 1;
} //kasus 3 dari algoritma AVL (rotasi kiri kanan)
else if (tinggi(temp.pKiri) - tinggi(temp.pKanan) >= 2 && tinggi(tem
p.pKiri.pKanan) >= tinggi(temp.pKiri.pKiri)) {
temp = rotasikirikanan(temp);//rekursif method rotasikirikanan d
engan parameter root
//hitung tinggi dari root
temp.tinggi = Math.max(tinggi(temp.pKiri), tinggi(temp.pKanan))
+ 1;
} //kasus 4 dari algoritma AVL (rotasi kanan kiri)
else if (tinggi(temp.pKanan) - tinggi(temp.pKiri) >= 2 && tinggi(tem
p.pKanan.pKiri) >= tinggi(temp.pKanan.pKanan)) {
temp = rotasikanankiri(temp);//rekursif method rotasikanankiri d
engan parameter root
temp.tinggi = Math.max(tinggi(temp.pKiri), tinggi(temp.pKanan))
+ 1;//untuk menghitung tinggi root
}
temp = temp.pInduk;//bergeser ke pInduk (root tree)
}
}
private Node rotasikiri(Node temp) {//method untuk rotasi kiri
Node parent = temp.pInduk;//inisialisasi parent = data temp pInduk
Node pKiri = temp.pKiri;//inisialisasi pkiri = data temp pKiri
temp.pKiri = pKiri.pKanan;//inisialisasi temp.pKiri = data pada cabang k
iri,ke kanan
//proses rotasi
if (temp.pKiri != null) {//jika temp,pKiri tidak kosong
temp.pKiri.pInduk = temp;
}
pKiri.pKanan = temp;
temp.pInduk = pKiri;
pKiri.pInduk = parent;
if (parent == null) {//jika parent kosong
root = pKiri;//pkiri menjadi root
} else if (parent.pKiri == temp) {//cabang kiri dari parent disimpan dal
am variabel temp
parent.pKiri = pKiri;//cabang kiri dari parent disimpan dalam variab
el pKiri
} else {
parent.pKanan = pKiri;//cabang kanan dari parent disimpan dalam vari
abel pKiri
}
//hitung tinggi subtree pKanan
temp.tinggi = Math.max(tinggi(temp.pKiri), tinggi(temp.pKanan)) + 1;//me
nghitung tinggi tree
temp = pKiri;//inisialisasi temp sebagai pKiri
return temp;//mengembalikan nilai temp
}
private Node rotasikanan(Node temp) {//method untuk rotasi kanan dengan para
meter temp
Node parent = temp.pInduk;//deklarasi variabel parent, dan inisialisasik
an menjadi data pInduk pada temp
Node pKanan = temp.pKanan;//deklarasi variabel pKanan, dan inisialisasik

an menjadi data pkanan pada temp


temp.pKanan = pKanan.pKiri;
if (temp.pKanan != null) {//jika data pada temp.pKanan tidak kosong
temp.pKanan.pInduk = temp;
}
pKanan.pKiri = temp;//data pkiri pada cabang kanan diinisialisasikan seb
agai temp
temp.pInduk = pKanan;//data pInduk pada temp diinisialisasikan sebagai p
kanan
pKanan.pInduk = parent;//data pInduk pada pKanan diinisialisasikan sebag
ai parent
if (parent == null) {//jika data pada parent kosong
root = pKanan;//root diinisialisasikan sebagai pKanan
} else if (parent.pKanan == temp) {//jika data pkanan pada parent = temp
parent.pKanan = pKanan;//data pkanan pada parent = pKanan
} else {
parent.pKiri = pKanan;//data pKiri pada parent = pKanan
}
//hitung tinggi subtree pKanan
temp.tinggi = Math.max(tinggi(temp.pKiri), tinggi(temp.pKanan)) + 1;//me
nghitung tinggi tree
temp = pKanan;//inisialisasi variabel temp
return temp;//mengembalikan nila temp
}
private Node rotasikirikanan(Node temp) {//method ini digunakan untuk rotasi
kanan kiri kanan
Node parent = temp.pInduk;//dekalrasi dan inisialisasi variabel dari cla
ss Node
Node pKiripKanan = temp.pKiri.pKanan;
temp.pKiri.pKanan = pKiripKanan.pKiri;
if (temp.pKiri.pKanan != null) {//jika data pKanan cabang pKiri pada var
iabel temp kosong
temp.pKiri.pKanan.pInduk = temp.pKiri;// data pInduk disimpan dalam
pKiri pada variabel temp
}
pKiripKanan.pKiri = temp.pKiri;
temp.pKiri.pInduk = pKiripKanan;
temp.pKiri = pKiripKanan.pKanan;
if (temp.pKiri != null) {//jika data pKiri pada temp tidak kosong
temp.pKiri.pInduk = temp;// data pInduk pada cabang kiri disimpan t
emp
}
pKiripKanan.pKanan = temp;
temp.pInduk = pKiripKanan;
pKiripKanan.pInduk = parent;
if (parent == null) {//jika data kosong
root = pKiripKanan;//root diinisialisasikan sebagai pKiriKanan
} else if (parent.pKiri == temp) {//data pKiri pada parent = data variab
el temp
parent.pKiri = pKiripKanan;//data pKiri pada parent disimpan pada va

riabel pKiriKanan
} else {
parent.pKanan = pKiripKanan;//data pKanan pada parent disimpan pada
variabel pkirikanan
}
temp = pKiripKanan;//inisialisasi variabel temp
return temp;//mengembalikan nilai pada variabel temp
}
private Node rotasikanankiri(Node temp) {//method ini digunakan untuk rotasi
kanan kiri, dengan parameter temp
Node parent = temp.pInduk;//dekalrasi dan inisialisasi variabel dari cla
ss Node
Node pKananpKiri = temp.pKanan.pKiri;
temp.pKanan.pKiri = pKananpKiri.pKanan;
if (temp.pKanan.pKiri != null) {//jika data pKiri cabang kanan dari temp
tidak kosong
temp.pKanan.pKiri.pInduk = temp.pKanan;//data pInduk pada temp.pKana
n.pKiri disimpan dalam pKanan pada temp
}
pKananpKiri.pKanan = temp.pKanan;
temp.pKanan.pInduk = pKananpKiri;
temp.pKanan = pKananpKiri.pKiri;
if (temp.pKanan != null) {//jika data pKanan pada temp tidak kosong
temp.pKanan.pInduk = temp;//maka data pada pInduk cabang kanan pada
temp disimpan dalam temp
}
pKananpKiri.pKiri = temp;
temp.pInduk = pKananpKiri;
pKananpKiri.pInduk = parent;
if (parent == null) {//jika data pada variabel parent kosong
root = pKananpKiri;//maka root diinisialisasikan data pada variabel
pKananKiri
} else if (parent.pKanan == temp) {//jika data pKanan pada parent = temp
parent.pKanan = pKananpKiri;//maka data pKanan pada parent diinisial
isasikan pKananKiri
} else {
parent.pKiri = pKananpKiri;//data pKiri pada parent diinisialisasika
n pKananKiri
}
temp = pKananpKiri;//inisialisasi variabel temp
return temp;//mengembalikan niali dari variabel temp
}
public boolean hapusNode(int dthapus) {//method bertipe boolean, digunakan u
ntuk menghapus data dengan parameter bertipe int
Node temp = root;//deklarasi temp dari class Node diinisialisasikan seba
gai root
Node parent = root;//deklarasi parent dari class Node diinisialisasikan
sebagai root
boolean isLeftChild = true;
while (temp.data != dthapus) {//perulangan untuk mencocokkan data dengan
data yang akan dihapus
parent = temp;//data pada variabel parent disimpan dalam temp
if (dthapus < temp.data) {//jika data yang dihapus lebih kecil dari

data temp
isLeftChild = true;
temp = temp.pKiri;//bergeser menuju cabang kiri
} else {
isLeftChild = false;
temp = temp.pKanan;//bergeser menuju cabang kanan
}
if (temp == null) {//jika temp kosong
return false;//maka mengembalikan nilai false
}
}
if (temp.pKiri == null && temp.pKanan == null) {//jika data hanya satu(r
oot)
if (temp == root) {//jika temp = root
root = null;//root kosong(dihapus)
} else if (isLeftChild) {//jika anak kiri
parent.pKiri = null;//data pKiri pada parent kosong(dihapus)
} else {
parent.pKanan = null;//data pKanan pada parent kosong(dihapus)
}
} else if (temp.pKanan == null) {//jika data cabang kanan kosong
if (temp == root) {//jika temp = root
root = temp.pKiri;//root = data pKiri pada temp
} else if (isLeftChild) {
parent.pKiri = temp.pKiri;// data pKiri pada parent disimpan dal
am data pKiri pada temp
} else {
parent.pKanan = temp.pKanan;//data pKanan pada parent disimpan d
alam temp pKanan
}
} else if (temp.pKiri == null) {//jika data pKiri pada temp kosong
if (temp == root) {//jika temp = root
root = temp.pKanan;//maka root diinisialisasikan pKanan pada tem
p
} else if (isLeftChild) {
parent.pKiri = temp.pKiri;//data pKiri pada parent disimpan dala
m pKiri pada temp
} else {
parent.pKanan = temp.pKanan;//data pKanan pada parent disimpan d
alam pKanan pada temp
}
} else {
Node successorParent = temp;//deklarasi dan inisialisasi variabel da
ri class Node
Node successor = temp;
Node bantu = temp.pKiri;//deklarasi dan inisialisasi variabel bantu
dari class Node
while (bantu != null) {//perulangan untuk bantu tidak kosong
successorParent = successor;
successor = bantu;//data pada successor disimpan dalam variabel
bantu
bantu = bantu.pKanan;//variabel bantu bergeser cabang kanan tree
}
if (successor != temp.pKiri) {//jika data pada succesor tidak samade
ngan data pKiri pada temp
successorParent.pKanan = successor.pKiri;//data pKanan pada succ
essorParent disimpan dalam pKiri pada successor
successor.pKiri = temp.pKiri;//data pKiri pada successor disimpa
n dalam pKiri paa temp
}

if (temp == root) {
root = successor;//root disimpan dalam variabel successor
} else if (isLeftChild) {
parent.pKiri = successor;//data pKiri pada parent disimpan dalam
variabel successor
} else {
parent.pKanan = successor;//data pKanan pada parent disimpan dal
am variabel successor
}
successor.pKiri = temp.pKanan;//data pKiri pada successor disimpan d
alam pKanan pada temp
}
rotation(temp);//rekursif method rotasi dengan parameter temp
return true; // mengembalikan nilai jika berhasil
}
public int tinggi() {//method ini digunakan untuk menghitung tinggi tree
return root.tinggi;//mengembalikan nilai tinggi dari root
}
private int tinggi(Node node) {//method ini digunakan untuk menghitung tingg
i tree dengan parameter, dari class Node
if (node == null) {//jika node kosong
return 0;//mengembalikan nilai 0
} else {
return node.tinggi;//mengembalikan nilai tinggi pada node
}
}
//method ini digunakan untuk menghitung node-node dari tree
public int jumlahNode() {
return jumlahNode(root);//mengembalikan nilai dari rekursif method jumla
hNode
}
public void inOrderTraversal() {//menampilkan data secara preorder
inOrder(root);//rekursif method inOrder dengan parameter root
}
private void inOrder(Node r) {//menampilkan data secara preorder
if (r == null) {//jika data pada parameter kosong
return;//mengembalikan data kosong
}
inOrder(r.pKiri);//rekursif method inOrder dengan parameter r.Pkiri(manu
ju ke cabang kiri)
System.out.printf("-%d", r.data);//cetak data pada variabel r
inOrder(r.pKanan);//rekursif method inOrder dengan parameter r.pKanan (m
enuju ke cabang kanan)
}
//hitung node-node dari tree
private int jumlahNode(Node node) {//method ini digunakan untuk menghitung j
umlah node dengan parameter dari class Node
if (node == null) {//jika node kosong
return 0;//maka mengembalikan nila 0
} else {
return 1 + jumlahNode(node.pKiri) + jumlahNode(node.pKanan);//mengem
balikan nilai rekursif jumlahNode dari cabang kiri+kanan+1(root)
}
}

public static void main(String[] args) {


AVLT t = new AVLT();
t.sisipDt(3);//memanggil method sisipDt dengan parameter 3
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
t.sisipDt(4);//memanggil method sisip data dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
t.sisipDt(6);//memanggil method sisip data dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
t.sisipDt(5);//memanggil method sisip data dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
t.sisipDt(15);//memanggil method sisip data dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
t.sisipDt(10);//memanggil method sisip data dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
t.sisipDt(20);//memanggil method sisip data dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
t.sisipDt(17);//memanggil method sisip data dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
t.sisipDt(25);//memanggil method sisip data dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
System.out.println("Setelah 3 dihapus");
t.hapusNode(3);//memanggil method hapusNode dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
System.out.println("Setelah 5 dihapus");
t.hapusNode(5);//memanggil method hapusNode dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
System.out.println("Setelah 10 dihapus");
t.hapusNode(10);//memanggil method hapusNode dan memberinya inputan
t.inOrderTraversal();//memanggil method inOrderTranversal(), untuk menam
pilkan data secara inOrder
System.out.println();
}
}

Vous aimerez peut-être aussi