Pertemuan 11 - Studi Kasus 1 | Sistem Folder Komputer (General Tree)

 

Studi Kasus 1

Nama: Hadryan Rizky Dimas Saputra
NRP: 5025251027
Kelas: Struktur Data (D) 2026
Pertemuan: 11

Source Code: pertemuan_11

Sistem Folder Komputer (General Tree)

Deskripsi (Fungsi) Program: 

Program ini merupakan aplikasi simulasi sistem folder pada komputer yang diimplementasikan menggunakan struktur data General Tree berbasis bahasa C++. Aplikasi ini dirancang untuk merepresentasikan hierarki direktori yang fleksibel dan dinamis, di mana setiap folder bertindak sebagai node yang memiliki relasi parent-child dan bebas menampung jumlah subfolder (children) yang tidak terbatas karena diakomodasi melalui memori dinamis. Melalui program ini, pengguna dapat mensimulasikan berbagai operasi fundamental yang umum ditemukan pada sistem operasi nyata, mulai dari pembuatan dan penghapusan folder beserta isinya, pencarian lokasi direktori spesifik menggunakan algoritma Depth First Search (DFS), hingga visualisasi struktur hierarki dan pelacakan jalur (path) menggunakan teknik navigasi rekursif seperti preorder maupun postorder traversal.

Code:

/*

Nama: Hadryan Rizky Dimas Saputra
NRP: 5025251027
Kelas: Struktur Data (D)
Konteks: Sistem Folder Komputer (General Tree)

*/

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Node {
public:
string name;
Node* parent;
vector<Node*> children;

Node(string folderName, Node* p=NULL) {
name = folderName;
parent = p;
}
};

class FolderTree {
private:
Node* root;

public:
FolderTree() {
root = new Node("Root");
}

// === GET ROOT ===
Node* getRoot() {
return root;
}

// === TAMBAH FOLDER ===
void addFolder(Node* parent, string folderName) {
Node* newFolder = new Node(folderName, parent);
parent->children.push_back(newFolder);
cout << "Folder '" << folderName << "' berhasil ditambahkan ke '" << parent->name << "'\n";
}

// === MENAMPILKAN TREE ===
void printTree(Node* node, int level = 0) {
if (node == NULL)
return;
for(int i = 0; i < level; i++) {
cout << " ";
}
if(level > 0)
cout << "|_ ";
cout << node->name << endl;
for (Node* child : node->children) {
printTree(child, level + 1);
}
}

// === PREORDER TRAVERSAL (Root -> Child) ===
void preorder(Node* node) {
if (node == NULL)
return;
cout << node->name << endl;
for (Node* child : node->children) {
preorder(child);
}
}

// === POSTORDER TRAVERSAL (Child -> Root) ===
void postorder(Node* node) {
if (node == NULL)
return;
for (Node* child : node->children) {
postorder(child);
}
cout << node->name << endl;
}

// === SEARCH FOLDER ===
Node* search(Node* node, string target) {
if (node == NULL)
return NULL;
if (node->name == target)
return node;
for (Node* child : node->children) {
Node* result = search(child, target);
if (result != NULL)
return result;
}
return NULL;
}

// === HITUNG JUMLAH FOLDER ===
int countFolder(Node* node) {
if (node == NULL)
return 0;
int total = 1;
for (Node* child : node->children) {
total += countFolder(child);
}
return total;
}

// === MENAMPILKAN PATH ===
void showPath(Node* node) {
if (node == NULL)
return;
vector<string> path;
Node* current = node;
while(current != NULL) {
path.push_back(current->name);
current = current->parent;
}
cout << "Path: ";
for(int i = path.size() - 1; i >= 0; i--) {
cout << path[i];
if(i != 0)
cout << "/";
}
cout << endl;
}

// === DELETE SUBTREE ===
void deleteSubtree(Node* node) {
if (node == NULL)
return;
for (Node* child : node->children) {
deleteSubtree(child);
}
delete node;
}

// === HAPUS FOLDER ===
void deleteFolder(string folderName) {
Node* target = search(root, folderName);
if(target == NULL) {
cout << "Folder tidak ditemukan!\n";
return;
}
if(target == root) {
cout << "Root tidak dapat dihapus!\n";
return;
}
Node* parent = target->parent;
for(auto it = parent->children.begin(); it != parent->children.end(); it++) {
if(*it == target) {
parent->children.erase(it);
break;
}
}
deleteSubtree(target);
cout << "Folder berhasil dihapus!\n";
}
};

int main() {
FolderTree tree;
Node* root = tree.getRoot();

// === MEMBUAT STRUKTUR FOLDER ===
tree.addFolder(root, "Documents");
tree.addFolder(root, "Pictures");
tree.addFolder(root, "Music");

Node* documents = tree.search(root, "Documents");
tree.addFolder(documents, "Kuliah");
tree.addFolder(documents, "Tugas");

// === TAMPILKAN TREE ===
cout << "\n===== STRUKTUR FOLDER =====\n";
tree.printTree(root);

// === PREORDER ===
cout << "\n===== PREORDER TRAVERSAL =====\n";
tree.preorder(root);

// === POSTORDER ===
cout << "\n===== POSTORDER TRAVERSAL =====\n";
tree.postorder(root);

// === SEARCH ===
cout << "\n===== SEARCH FOLDER =====\n";
Node* result = tree.search(root, "Tugas");
if (result != NULL) {
cout << "Folder ditemukan : " << result->name << endl;
tree.showPath(result);
} else {
cout << "Folder tidak ditemukan\n";
}

// === COUNT FOLDER ===
cout << "\n===== JUMLAH FOLDER =====\n";
cout << "Total Folder : " << tree.countFolder(root) << endl;

// === DELETE FOLDER ===
cout << "\n===== HAPUS FOLDER =====\n";
tree.deleteFolder("Pictures");

// === TAMPILKAN TREE SETELAH DELETE ===
cout << "\n===== STRUKTUR SETELAH DELETE =====\n";
tree.printTree(root);

return 0;
}

Output:

Penjelasan:

Node(string folderName, Node* p=NULL)

    Ini adalah konstruktor dari struktur node. Berfungsi untuk menginisialisasi folder baru dengan cara menyimpan nama folder ke dalam variabel name dan mengaitkannya dengan alamat dari parent folder pembawanya.

FolderTree()

    Merupakan konstruktor utama untuk menginisialisasi tree. Saat objek tree pertama kali dibentuk, fungsi ini akan langsung melakukan alokasi memori dinamis untuk membuat node utama bernama "Root" yang menjadi titik puncak hierarki dari keseluruhan sistem file.

getRoot()

    Berfungsi sebagai getter yang mengembalikan pointer dari node "Root" agar dapat digunakan oleh fungsi lain sebagai titik awal penelusuran.

addFolder(Node* parent, string folderName)

    Berfungsi untuk menyisipkan direktori baru di dalam hierarki. Fungsi ini membuat alokasi memori untuk objek node baru dan memasukkannya ke bagian belakang dari daftar vector children milik node parent yang telah ditentukan.

printTree(Node* node, int level = 0)

    Berfungsi menampilkan struktur direktori secara visual. Menggunakan metode rekursif di mana setiap penambahan level kedalaman child akan menambahkan indentasi spasi (  ) dan garis hierarki (|_), sehingga menghasilkan tampilan bertingkat yang rapi layaknya visualisasi file explorer di sistem operasi nyata.

preorder(Node* node)

    Melakukan traversal dengan urutan Root ke Child. Program akan mencetak nama node yang sedang dikunjungi terlebih dahulu, sebelum masuk ke dalam rekursi untuk menelusuri dan mencetak seluruh subfoldernya dari urutan paling kiri hingga ke kanan.

postorder(Node* node)

    Melakukan traversal dengan urutan Child ke Root. Program akan menelusuri terlebih dahulu hingga ke node child terdalam dan mencetak namanya, barulah fungsi berjalan mundur ke atas untuk mencetak nama node parent-nya.

search(Node* node, string target)

    Berfungsi untuk mencari lokasi folder spesifik menggunakan teknik pencarian Depth First Search (DFS). Jika node dengan nama yang sesuai ditemukan, program akan mengembalikan referensi alamat (pointer) dari node tersebut. Jika setelah ditelusuri hingga ujung percabangan tidak ada yang cocok, fungsi akan mengembalikan nilai NULL.

countFolder(Node* node)

    Berfungsi menghitung jumlah seluruh direktori yang ada di dalam tree. Program menetapkan nilai 1 untuk node induk yang aktif, lalu menjumlahkannya dengan nilai kembalian fungsi ini secara rekursif terhadap seluruh child di bawahnya.

showPath(Node* node)

    Berfungsi menampilkan alamat rute (path) lengkap dari Root menuju direktori tujuan. Fungsi memanfaatkan pointer parent untuk melangkah mundur dari bawah ke atas, menyimpan urutannya di dalam vector, dan kemudian mencetaknya dari indeks terakhir ke awal secara terbalik dengan dibatasi garis miring (/).

deleteSubtree(Node* node)

    Berfungsi membersihkan dan melepaskan alokasi memori dinamis di belakang layar. Fungsi ini menelusuri setiap percabangan anak dan melakukan delete node dari posisi paling bawah ke atas untuk memastikan tidak ada memori sisa (memory leak).

deleteFolder(string folderName)

    Fungsi operasional untuk menghapus suatu direktori dan seluruh subfolder di dalamnya (subtree). Fungsi ini mencari folder target terlebih dahulu. Jika ditemukan dan target tersebut bukanlah "Root", maka fungsi akan mencabut pointer target dari daftar children parent-nya, lalu memanggil deleteSubtree untuk menghancurkan seluruh isi folder tersebut.

Komentar

Postingan populer dari blog ini

Pertemuan 12 - BTree & BST