Oke, kita masuk ke modul empat! Setelah kemarin kita main-main sama data yang lurus-lurus aja (linear) kayak Linked List, Stack, dan Queue, sekarang kita kenalan sama struktur data yang punya cabang: Tree.
Bayangin aja struktur folder di komputermu, atau silsilah keluarga. Ada satu folder/leluhur utama (disebut root), terus dia punya anak (child), anaknya punya anak lagi, dan seterusnya. Itulah konsep dasar Tree. Setiap item di dalam tree kita sebut node, dan node yang udah nggak punya anak lagi kita sebut leaf (daun).
Binary Search Tree (BST): Tree yang Teratur
Ada banyak jenis Tree, tapi yang paling sering jadi dasar adalah Binary Search Tree (BST). Kenapa? Karena dia sangat teratur. Aturannya simpel:
Untuk setiap node, semua data di cabang kiri-nya harus lebih kecil, dan semua data di cabang kanan-nya harus lebih besar.
Aturan ini bikin proses pencarian data jadi super cepat, mirip kayak Binary Search yang udah kita pelajari.
Cetakan Node untuk Tree
Node pada Tree sedikit beda. Selain nyimpen data, dia punya dua referensi: left buat anak kiri, dan right buat anak kanan.
class Node { int data; Node left, right;
public Node(int data) { this.data = data; left = right = null; }}Implementasi Binary Search Tree
Sekarang kita bikin class buat Tree-nya. Kita mulai dengan root yang jadi titik awal.
class BinarySearchTree { Node root;
// Method utama untuk memasukkan data public void insert(int data) { root = insertRec(root, data); }
// Method rekursif untuk mencari posisi yang pas private Node insertRec(Node current, int data) { if (current == null) { return new Node(data); // Posisi kosong ditemukan, buat node baru }
if (data < current.data) { current.left = insertRec(current.left, data); } else if (data > current.data) { current.right = insertRec(current.right, data); }
return current; }
// Method utama untuk mencari data public boolean find(int data) { return findRec(root, data); }
// Method rekursif untuk menelusuri tree private boolean findRec(Node current, int data) { if (current == null) { return false; // Udah mentok, data nggak ada }
if (data == current.data) { return true; // Ketemu! }
return data < current.data ? findRec(current.left, data) // Cari di kiri : findRec(current.right, data); // Cari di kanan }}Logikanya rekursif, artinya method-nya manggil dirinya sendiri buat turun ke cabang kiri atau kanan sampe ketemu posisi yang pas.
Tree Traversal: Jalan-Jalan di Dalam Tree
Kalau mau nampilin semua data di dalam Tree, gimana caranya? Ada tiga cara umum buat “jalan-jalan” (traversal) di Tree, dan ketiganya ini penting banget.
1. In-Order Traversal (Kiri - Akar - Kanan)
Cara ini bakal ngunjungin anak kiri, terus si node itu sendiri, baru ke anak kanan. Kalau kita lakuin di BST, hasilnya bakal jadi data yang terurut, lho! Keren kan?
public void printInOrder(Node node) { if (node != null) { printInOrder(node.left); System.out.print(node.data + " "); printInOrder(node.right); }}2. Pre-Order Traversal (Akar - Kiri - Kanan)
Kalau yang ini, kita catet dulu data node saat ini, baru lanjut ke anak kiri, terus ke anak kanan. Biasanya cara ini dipake buat nyalin (copy) sebuah Tree.
public void printPreOrder(Node node) { if (node != null) { System.out.print(node.data + " "); printPreOrder(node.left); printPreOrder(node.right); }}3. Post-Order Traversal (Kiri - Kanan - Akar)
Nah, kalau yang ini kebalikannya. Kita beresin dulu semua anak kiri, terus semua anak kanan, baru kita catet data node saat ini. Cara ini sering dipake buat proses ngehapus node dari Tree.
public void printPostOrder(Node node) { if (node != null) { printPostOrder(node.left); printPostOrder(node.right); System.out.print(node.data + " "); }}Penutup Modul 4
Tree ini emang kelihatan ribet di awal, tapi konsepnya kuat banget. Kemampuannya buat nyimpen data secara hierarkis sambil tetep efisien buat pencarian bikin Tree jadi salah satu struktur data paling penting.
Di modul terakhir, kita bakal bahas Graph, yaitu bentuk yang lebih umum dari Tree di mana aturannya lebih bebas. Sampai jumpa di sana!