Struktur Data – Nested Linked List

Mahir Koding – Struktur Data – Nested Linked List adalah struktur data linear yang mempunyai linked list lain di dalamnya. Ibarat sebuah “kotak”, yang di dalamnya mempunyai kotak lagi. Struktur data nested linked list digunakan untuk menyimpan linked list secara terkelompok dan terkategorikan satu sama lain. Misalnya saja sebuah list kelas akan mempunyai linked list siswa di dalamnya. Setiap linked list data yang sifatnya berhubungan dengan parent data, dapat dikelompokkan menurut kategorinya masing-masing. Dengan demikian setiap data akan terorganisir dengan baik dan terstruktur dengan sangat jelas.

Inisialisasi Struktur

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//penomoran ruangan kelas
int classNumber=1;

//struct data siswa
struct student{
	//variabel nama mahasiswa
	char studentname[100];
	//pointer menunjuk siswa sebelumnya dan sesudahnya
	student *studentNext, *studentPrev;
};

//struct data kelas
struct classroom{
	//variabel nama kelas
	char className[100];
	//variabel nomor kelas
	int classNumber;
	//pointer menunjuk kelas sebelumnya dan sesudahnya
	classroom *classroomNext, *classroomPrev;
	//pointer menunjuk siswa pertama, siswa terakhir dan variabel temp current
	student *studentHead, *studentTail, *studentCurr;
}*classroomHead, *classroomTail, *classroomCurr;
//pointer menunjuk kelas pertama, kelas terakhir dan variabel temp current

Print Data (cetak semua data)

//fungsi print semua data kelas beserta siswanya
void printData(){
	//set data kelas pertama ke variabel temp
	classroomCurr = classroomHead;
	//looping selama tidak kosong kelasnya
	while(classroomCurr!=NULL){
		//cetak nama kelas dan nomor kelasnya
		printf("%d. %s\n", classroomCurr->classNumber, classroomCurr->className);
		//set data siswa pertama dalam kelas ke variabel temp
		classroomCurr->studentCurr = classroomCurr->studentHead;
		//looping selama tidak kosong siswanya
		while(classroomCurr->studentCurr){
			//cetak nama siswanya
			printf("  - %s\n", classroomCurr->studentCurr->studentname);
			//lanjutkan pointer next ke list siswa selanjutnya
			classroomCurr->studentCurr = classroomCurr->studentCurr->studentNext;
		}
		//lanjutkan pointer next ke list kelas selanjutnya
		classroomCurr=classroomCurr->classroomNext;
	}
}

Push Classroom (tambah kelas baru)

//fungsi insert kelas baru
void pushClassRoom(char classroomname[]){
	//alokasikan memory baru
	classroomCurr = (classroom *)malloc(sizeof(classroom));
	//isi data baru sesuai data yang dibutuhkan
	strcpy(classroomCurr->className, classroomname);
	//simpan juga nomor kelasnya
	classroomCurr->classNumber = classNumber; classNumber++;
	//buat semua pointer ke NULL dengan anggapan belum ada hubungan data satu sama lain
	classroomCurr->classroomNext = classroomCurr->classroomPrev = NULL;
	classroomCurr->studentHead = classroomCurr->studentTail = classroomCurr->studentCurr = NULL;
	
	//cek dahulu apakah data yang ingin dimasukkan adalah data pertama karena data
	//pertama saat ini sedang kosong
	if(classroomHead==NULL){
		//jika iya, set kelas pertama dan terakhir adalah data yang barusan kita insert
		classroomHead = classroomTail = classroomCurr;
	}else{
		//jika tidak, insert data kelas baru dan bagian TAIL class.
		classroomTail->classroomNext = classroomCurr;
		classroomCurr->classroomPrev = classroomTail;
		classroomTail = classroomCurr;
	}
}

Push Student (tambah siswa baru)

//fungsi insert student baru dalam class
//menerima 2 parameter
//yang pertama adalah nomor kelas
//yang kedua adalah nama siswa
void pushStudent(int targetClassNumber, char studentName[]){
	//flag variabel sebagai penanda apakah kelas yang dituju ada atau tidak
	int found=-1;

	//mulai looping mencari kelas yang dimaksud
	classroomCurr = classroomHead;
	while(classroomCurr!=NULL && found==-1){
		//jika ketemu, ganti value flag dan lakukan break agar tidak berganti kelas
		if(classroomCurr->classNumber==targetClassNumber){ found=1; break; } 
		classroomCurr=classroomCurr->classroomNext;
	}
	//jika ketemu
	if(found==1){
		//insert data siswa baru
		classroomCurr->studentCurr = (student*)malloc(sizeof(student));
		strcpy(classroomCurr->studentCurr->studentname, studentName);
		//kosongkan pointernya terlebih dahulu
		classroomCurr->studentCurr->studentNext = classroomCurr->studentCurr->studentPrev = NULL;
		
		//jika belum ada data
		//maka insert data baru pertama kali dan otomatis akan menjadi head dan tail
		if(classroomCurr->studentHead==NULL){
			classroomCurr->studentHead = classroomCurr->studentTail = classroomCurr->studentCurr;
		//jika sudah ada data 
		}else{
			//insert data student ke dalam kelas dengan posisi terakhir
			classroomCurr->studentTail->studentNext = classroomCurr->studentCurr;
			classroomCurr->studentCurr->studentPrev = classroomCurr->studentTail;
			classroomCurr->studentTail = classroomCurr->studentCurr;
		}
	}else{
		printf("Class not found.\n");
	}
}

Delete Classroom (hapus data kelas)

//fungsi hapus ruang kelas
//menerima 1 parameter yaitu nomor kelas
void deleteClassRoom(int targetClassNumber){
	//flag variabel untuk menandakan apakah kelas sudah ditemukan atau belum
	int found=-1;
	//buat 2 variabel penampung siswa dan kelas
	student *tempStudent;
	classroom *tempClass;

	//mulai looping mencari kelas yang dimaksud
	classroomCurr = classroomHead;
	while(classroomCurr!=NULL){
		//jika ketemu kelasnya, ganti value flag dan lakukan break agar kelas tidak berganti
		if(classroomCurr->classNumber == targetClassNumber){ found=1; break; }
		classroomCurr = classroomCurr->classroomNext;
	}
	//jika sudah ketemu
	if(found==1){
		//looping sekaligus lakukan POP HEAD untuk menghapus semua data siswa dalam kelas itu
		//siswa di dalamnya wajib dihapus agar tidak memory yang sudah tidak digunakan tidak "nyasar"
		while(classroomCurr->studentHead!=NULL){
			tempStudent = classroomCurr->studentHead;
			if(classroomCurr->studentHead==classroomCurr->studentTail){
				classroomCurr->studentHead=classroomCurr->studentTail=NULL;
			}else{
				classroomCurr->studentHead=classroomCurr->studentHead->studentNext;
			}
			free(tempStudent);
		}
		//jika seluruh siswanya sudah kosong, sekarang saatnya menghapus kelasnya
		//tampung data kelas yang ingin dihapus ke temp variabel
		//lakukan validasi terlebih dahulu
		tempClass = classroomCurr;
		//jika hanya ada 1 data (delete data terakhir)
		if(classroomHead==classroomTail){
			//set head dan tail menjadi NULL
			classroomHead = classroomTail = NULL;
		//jika kebetulan data yang ingin dihapus adalah data pertama, lakukan pop HEAD
		}else if(classroomCurr==classroomHead){
			classroomHead=classroomHead->classroomNext;
			classroomHead->classroomPrev=NULL;
		//jika kebetulan data yang ingin dihapus adalah data terakhir, lakukan pop TAIL
		}else if(classroomCurr==classroomTail){
			classroomTail=classroomTail->classroomPrev;
			classroomTail->classroomNext=NULL;
		//jika datanya ditengah, maka kita akan melakukan "penyambungan data"
		}else{
			classroomCurr->classroomPrev->classroomNext = classroomCurr->classroomNext;
			classroomCurr->classroomNext->classroomPrev = classroomCurr->classroomPrev;
		}
		free(tempClass);
	}else{
		printf("Class not found.\n");
	}
}

Delete Student (hapus data siswa)

//fungsi untuk menghapus siswa
//menerima 2 parameter
//yang pertama adalah nomor kelas tempat si siswa yang akan dihapus
//yang kedua adalah nama siswa yang ingin dihapus
void deleteStudent(int targetClassNumber, char studentName[]){
	int foundClass=-1;
	int foundStudent=-1;
	student *tempStudent;

	//kita akan mencari apakah kelas yang siswanya ingin dihapus tersedia atau tidak
	classroomCurr = classroomHead;
	while(classroomCurr!=NULL){
		if(classroomCurr->classNumber == targetClassNumber){ foundClass=1; break; }
		classroomCurr = classroomCurr->classroomNext;
	}
	//jika kelasnya ada
	if(foundClass==1){
		//lakukan pencarian lagi apakah siswanya ada dalam kelas tersebut
		classroomCurr->studentCurr = classroomCurr->studentHead;
		while(classroomCurr->studentCurr!=NULL){
			//pengecekan dilakukan dengan bantuan strcmpi (insensitive case)
			if(strcmpi(classroomCurr->studentCurr->studentname,studentName)==0){ foundStudent=1; break; }
			classroomCurr->studentCurr = classroomCurr->studentCurr->studentNext;
		}
		//jika ada siswanya
		if(foundStudent==1){
			//delete siswanya dan pastikan sudah divalidasi terlebih dahulu
			tempStudent = classroomCurr->studentCurr;
			//jika hanya ada 1 data (kita akan menghapus data satu satunya)
			if(classroomCurr->studentHead==classroomCurr->studentTail){
				classroomCurr->studentHead = classroomCurr->studentTail = NULL;
			//jika kebetulan siswa yang ingin dihapus adalah siswa pertama
			//lakukan pop Head
			}else if(classroomCurr->studentCurr == classroomCurr->studentHead){
				classroomCurr->studentHead = classroomCurr->studentHead->studentNext;
				classroomCurr->studentHead->studentPrev = NULL;
			//jika kebetulan siswa yang ingin dihapus adalah siswa terakhir
			//lakukan pop Tail
			}else if(classroomCurr->studentCurr == classroomCurr->studentTail){
				classroomCurr->studentTail = classroomCurr->studentTail->studentPrev;
				classroomCurr->studentTail->studentNext = NULL;
			//jika siswa yang ingin dihapus ada di tengah
			//lakukan penyambungan linked list
			}else{
				classroomCurr->studentCurr->studentPrev->studentNext = classroomCurr->studentCurr->studentNext;
				classroomCurr->studentCurr->studentNext->studentPrev = classroomCurr->studentCurr->studentPrev;
			}
			free(tempStudent);
		}else{
			printf("Student not found.\n");
		}
	}else{
		printf("Class not found.\n");
	}
}

Konsep “Menyambung Data” dalam Linked List

Main Function

int main(){
	pushClassRoom("XII A");
	pushClassRoom("XII B");
	pushClassRoom("XII C");
	pushStudent(1, "Hery Vandoro");
	pushStudent(1, "Tono Budiman");
	pushStudent(3, "Tini Hartini");
	pushStudent(2, "Susi Suherman");
	pushStudent(2, "John Doe");
	
	deleteStudent(2, "Foo Bar");
	deleteStudent(1, "Hery Vandoro");

	deleteClassRoom(2);

	pushClassRoom("XII D");
	printData();
	getchar();
}

Source code secara lengkap bisa dicek ke github saya, di link ini.

Jika ada pertanyaan yang kurang jelas silahkan berkomentar di bawah. Atau, jika ingin request tutorial juga dapat ke halaman ini. Dukung terus Mahir Koding agar dapat selalu mengupdate artikel dengan share dan like artikel ini. Terima Kasih.