Skip to main content

Review Material

Review Material

SUDAH KENAL DEKAT DENGAN LINKED LIST BELUM?

Sebelum Anda membaca materi ini , ada baiknya anda sudah memahami Data Structure dasar seperti penggunaan struct , array , malloc , free()  dan pointer .  Dengan begitu , Anda dapat memahami materi ini dengan baik !

A. Oke , jadi apa itu Linked List ?

  • Linked List adalah struktur data dinamis yang pengimplementasiannya memakai pointer yang mengarah pada suatu nodes  ( elemen ) dan strukturnya menyesuaikan size data yang dibutuhkan atau dengan kata lain fleksibel dimana dapat membesar atau mengecil sesuai data yang telah diinput .

Kok Mirip Array ? Terus apa bedanya ?

Nah , prinsip Linked List bersama Array itu sama , tetapi ditinjau dari implementasi penggunaannya mau dimana , mau dipakai pada apa , dan seefektif apa pengaplikasiannya . Untuk lebih jelasnya , simak kutipan tabel di bawah ini ^_^ !




B. Jenis-jenis Linked List sendiri gimana ?

Nah Linked List sendiri ada 3 "spesies"-nya . Apa aja sih? , ada :
  1. Single Linked List / Singly Linked List  /  Senarai Berantai 

    Nah spesies yang ini hanya menggunakan satu variable pointer saja dalam menyimpan data.
    Pada Linked List , terdapat 3 bagian utama  krusial , yakni Head , Mid , dan Tail .

    Hasil gambar untuk single linked list in c
  2. Circular Linked List
    Nah untuk yang satu ini memiliki karakteristik dimana node yang pertama akan menunjuk ke node terakhir dan sebaliknya sehingga ia tidak memiliki nilai atau NULL pada medan sambungannya karena tail menunjuk ke head.

    Hasil gambar untuk circular linked list in c
  3. Double Linked List / Doubly Linked List
    Sama seperti Single Linked List , hanya saja terdapat pointer prev dan next . Nah pointer prev ini punya peran penting untuk mempertahankan pointer next dan juga menggeser mundur nodes ( elemen data ) sehingga linked list ini sangat fleksibel namun membutuhkan tambahan memori yang banyak.


    Hasil gambar untuk double linked list bahasa c
C. Sudah mulai rumit ? Pahamin cara kerjanya masing-masing yuk !

Nah sebelum masuk protokol cara kerjanya masing-masing , kita overview dulu nih , di Linked List ini ada terminologi khusus dan tekniknya . Seperti yang sudah kalian baca di atas , asing gak sih ada istilah Head , Mid , Tail ? 

Head ini sendiri adalah elemen / node  yang berada pada posisi pertama linked list , sedangkan Tail adalah elemen atau node yang berada pada posisi terakhir linked list . Nah udah tau kan Mid itu apa jadinya ? 

Adapun teknik khusus pada Linked List , apa aja tuh ? 

  • PUSH / INSERT untuk menambah data.
    • PushHead – Menambah data ke barisan/posisi paling awal
    • PushTail – Menambah data ke barisan/posisi paling akhir
    • PushMid – Menambah data ke barisan/posisi di tengah (disorting dulu ya ! HARUS !)
  • POP / DELETE untuk menghapus data.
    • PopHead – Menghapus data paling awal
    • PopTail – Menghapus data paling akhir
    • PopMid – Menghapus data di tengah (sesuai parameter value)
Oke , mari kita simak satu per satu dan basic understanding code nya !

1. Single Linked List
Coba kalian bayangkan struktur kereta dari kereta pilot depannya hingga belakang , nah untuk Single Linked List strukturnya juga begitu . 
Hasil gambar untuk single linked list in c

Nah untuk Insert/Push data baik dari Head atau Tail-nya disini bagaimana sih ? Kurang lebih codingannnya seperti di bawah ini :

Untuk Push Head :


Kita harus mengalokasikan memori dulu untuk struct Facebook , lalu dia akan mengecek dan men-sanitize dan menetapkan isi Head , Tail , Mid ( dalam coding ini Curr ) bernilai NULL atau tidak ada terlebih dahulu ( jikalau Head isinya kosong ) , namun jika sudah terisi ,head  akan diassign ke curr->next lalu si curr(mid) akan menjadi head yang baru.

Sedangkan untuk push Tail / Belakang :
Sama dengan head , namun perbedaannya adalah ketika head nya tidak kosong , maka si Mid(curr) akan di-assign menjadi variable selanjutnya dari si Tail ( karena dari belakang ) , sehingga si Mid menjadi Tail yang baru dan wadah setelah tail di-NULL-kan.  

Nah , buat delete/pop Head gimana ? Begini :


Toh logikanya kalau Head-nya kosong tidak ada data, untuk apa kita Pop / Delete Data kan? Nah yang berbeda adalah jika ia terdapat isinya , kita memakai library-built-in function yakni free() untuk mengosongkan data pada variable yang dituju.

Untuk pop/delete Tail :



2. Double Linked List

Untuk Insert Data pada Head :

Untuk Insert Data dari belakang ( PushTail ) :

Untuk pop Head nya bagaimana ? Begini :

Sedangkan untuk pop Tailnya :

3. Circular Linked List

Nah , untuk Linked List yang satu ini dapat diterapkan pada 2 Linked List di atas atau istilahnya di-fusion !
A. Circular Singly Linked List
Single : artinya field pointer-nya hanya satu buah saja dan satu arah. 
Circular : artinya pointer next-nya akan menunjuk pada dirinya sendiri sehingga berputar.


Hasil gambar untuk circular linked list in c
B. Circular Doubly Linked List
Terdapat 3 field , apa saja sih ?
-- 1 field pointer yang menunjuk pointer berikutnya "next",
-- 1 field menunjuk pointer sebelumnya " prev ",
-- 1 field yang berisi data untuk node tersebut .

Hasil gambar untuk circular doubly linked list in c

HASH TABLE + BINARY SEARCH TREE ?
APAAN SIH ? ( in general  )


Halo semuanya ! Kali ini mimin Peik mau ngenalin kalian apa sih itu Hashing Table dan Binary Tree yang tentunya adalah topik lanjutan Data Structure . Para pembaca sebelumnya dituntut sudah mengerti cara kerja Data Structure secara dasar seperti protokol Linked List dan spesies-spesiesnya ya ! ^ 0 ^





A. Hashing Table / Hash Table

Apa sih ? Namanya makin aneh-aneh aja . Hash Table disini yang dimaksud bukan langsung menjadi hash yang kalian bayangkan MD5 , SHA1 dan sebagainya ya, lebih ke protokol cara kerjanya dulu !  ADALAH struktur data yang terdiri dari sebuah TABEL dan fungsi yang memetakan nilai KUNCI untuk setiap record dalam suatu angka . Ya intinya jadi kayak KAMUS gitu guys ! :o Jadi bisa diasumsikan bahwa nanti kalian tinggal memberikan sebuah (key) lalu kalian bakal diarahin ke entri tujuan yang mengandung key yang kalian kasih , sehingga AKSES DIPERMUDAH .


Hasil gambar untuk hash table data structure


Sebelumnya , kalian wajib tahu juga cara kerja Hashing nih !
Nah idenya sih seperti mengubah string menjadi suatu bilangan dengan suatu fungsi lalu di modulo.
Nanti kompleksitas untuk setiap operasi adalah O(k) dimana K = panjang string .
Kalau hashing-nya sendiri adalah protokol pengubah objek menjadi serangkaian angka/karakter bahkan sejenisnya.
Misal , seperti:


arr["inipeik"] = 5;
printf("%d\n", arr["inipeik"]);

Collision Case

Nah , kalau di Hash Table keys nya akan diproses untuk menghasilkan suatu indeks baru pada elemen yang dibutuhkan . TAPI PERLU DIPERHATIKAN , kalau terdapat indeks yang sama yang dihasilkan dari hashing , dapat terjadi adanya collision . Untuk menghindari ini , harus dipilih hash function yang sesuai.
Solusi pertama adalah dengan menggunakan teknik CHAINING ( sumber dari https://www.programiz.com/dsa/hash-table )



Collision resolution in hash table

Jika fungsi hashing menghasilkan index yang sama pada elemen-elemen , elemen-elemen tersebut akan disimpan di INDEKS YANG SAMA dengan menggunakan doubly linked list .



// Implementing hash table in C

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

struct set
{
  int key;
  int data;
};
struct set *array;
int capacity = 10;
int size = 0;

int hashFunction(int key)
{
  return (key % capacity);
}
int checkPrime(int n)
{
  int i;
  if (n == 1 || n == 0)
  {
    return 0;
  }
  for (i = 2; i < n / 2; i++)
  {
    if (n % i == 0)
    {
      return 0;
    }
  }
  return 1;
}
int getPrime(int n)
{
  if (n % 2 == 0)
  {
    n++;
  }
  while (!checkPrime(n))
  {
    n += 2;
  }
  return n;
}
void init_array()
{
  capacity = getPrime(capacity);
  array = (struct set *)malloc(capacity * sizeof(struct set));
  for (int i = 0; i < capacity; i++)
  {
    array[i].key = 0;
    array[i].data = 0;
  }
}

void insert(int key, int data)
{
  int index = hashFunction(key);
  if (array[index].data == 0)
  {
    array[index].key = key;
    array[index].data = data;
    size++;
    printf("\n Key (%d) has been inserted \n", key);
  }
  else if (array[index].key == key)
  {
    array[index].data = data;
  }
  else
  {
    printf("\n Collision occured  \n");
  }
}

void remove_element(int key)
{
  int index = hashFunction(key);
  if (array[index].data == 0)
  {
    printf("\n This key does not exist \n");
  }
  else
  {
    array[index].key = 0;
    array[index].data = 0;
    size--;
    printf("\n Key (%d) has been removed \n", key);
  }
}
void display()
{
  int i;
  for (i = 0; i < capacity; i++)
  {
    if (array[i].data == 0)
    {
      printf("\n array[%d]: / ", i);
    }
    else
    {
      printf("\n key: %d array[%d]: %d \t", array[i].key, i, array[i].data);
    }
  }
}

int size_of_hashtable()
{
  return size;
}

int main()
{
  int choice, key, data, n;
  int c = 0;
  init_array();

  do
  {
    printf("1.Insert item in the Hash Table"
         "\n2.Remove item from the Hash Table"
         "\n3.Check the size of Hash Table"
         "\n4.Display a Hash Table"
         "\n\n Please enter your choice: ");

    scanf("%d", &choice);
    switch (choice)
    {
    case 1:

      printf("Enter key -:\t");
      scanf("%d", &key);
      printf("Enter data -:\t");
      scanf("%d", &data);
      insert(key, data);

      break;

    case 2:

      printf("Enter the key to delete-:");
      scanf("%d", &key);
      remove_element(key);

      break;

    case 3:

      n = size_of_hashtable();
      printf("Size of Hash Table is-:%d\n", n);

      break;

    case 4:

      display();

      break;

    default:

      printf("Invalid Input\n");
    }

    printf("\nDo you want to continue (press 1 for yes): ");
    scanf("%d", &c);

  } while (c == 1);
}


Solusi kedua adalah dengan menggunakan Open Addressing . Pada teknik ini , semua elemen akan disimpan di dalam hash table itu sendiri. Ukuran dari tabelnya pastinya harus lebih besar sama dengan total keys . Nah salah satunya adalah dengan menggunakan Linear Probing .


Intinya dia akan melakukan pengecekan pada slot selanjutnya dimana:

func(k, i) = (newfunc(k) + i) mod m

//newfunc adalah fungsi baru

Adapun quadratic probing dan double hashing technique untuk me-resolve collision case ini juga ^0^.

Blockchain Case

Pada blockchain , implementasi hash table ini sebenarnya dipakai , namun lebih distributif makanya disebut dengan DHT ( Distributed Hash Table ).
DHT disini protokolnya sama dengan Hash Table biasa yakni menyimpan suatu nilai key yang terdapat di berbagai jumlah nodes pada network dengan menggunakan deterministic algorithm , dimana algoritma ini akan menghasilkan output yang sama .


Lalu juga digunakan adanya routing algorithm yang akan melakukan request pada hash table tanpa mengetahui setiap node di network. Contohnya saja yang dipakai adalah Chord DHT .


Hasil gambar untuk hash table in blockchain




B. Binary Search Tree

Nah , mimin harap kalian semua jadi mengerti apa itu Hash Table . Sekarang kita move on ke topik selanjutnya yakni Binary Tree ! Apa sih Binary Search Tree itu sendiri ?

Oke sebelum kalian paham BST ini , kalian harus tahu apa itu Tree?
Tree sendiri bisa dikatakan sebagai suatu struktur data berupa bentuk pohon terbalik yang menggambarkan hubungan hierarkis antar elemen.


Nah kalau pada Binary Tree sendiri , dia hanya memiliki maksimal 2 cabang saja.

Oke sekarang kita masuk pada pembahasan Binary Search Tree , konsepnya sama saja dengan Binary Tree namun terdapat aturan bahwa setiap child node di sebelah kiri harus lebih kecil nilainya dari pada root node dan vice-versa !



Pada Binary Search Tree , terdapat 3 cara unutk melakukan traversing ,yakni:
1. Pre-order = print data lalu traverse ke kiri lalu traverse ke kanan
2. In-Order =  traverse kiri , print data , lalu traverse kanan
3. Post-order  = traverse kiri, traverse kanan lalu print data


Task Source Code: ( GSLC -Tuesday-2020 )

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

struct node{
char listed[109];
long long int harga;
int jumlah;
node *next,*prev;
}*head,*tail;

unsigned long long int starting_price=(rand()%100)*100;

node *createNode(char *words, int deft){
node* belanja = (node*)malloc(sizeof(node)); 
strcpy(belanja->listed,words);
belanja->jumlah = deft;
belanja->harga = belanja->jumlah*starting_price;
belanja->next = NULL;
belanja->prev = NULL;
return belanja;
}

void pushHead(char *words, int deft){
node *curr = createNode(words,deft);
curr->next = head;
head->prev = curr;
head = curr;
}

void pushTail(char *words, int deft){
node *curr = createNode(words,deft);
tail->next = curr;
curr->prev = tail;
tail = curr;
}

void pushMid(char *words, int deft){
node *curr = createNode(words,deft);
node *ptr=head;
int cmp;
while(ptr != NULL){
if(strcmp(ptr->next->listed,words)>0){
curr->next = ptr->next;
curr->prev = ptr;

ptr->next->prev = curr;
ptr->next = curr;
break;
}
ptr = ptr->next;
}
}

void push(char *words, int deft){
node *curr = createNode(words,deft);
if(head==NULL){
head=tail=curr;
} else if(strcmp(head->listed,words)>0){
free(curr);
pushHead(words,deft);
} else if(strcmp(tail->listed,words)<=0){
free(curr);
pushTail(words,deft);
} else {
free(curr);
pushMid(words,deft);
}
}

void update(char *words, int new_quant){
int count=-1;
node *ptr=head;
while(ptr!=NULL){
if(strcmp(ptr->listed,words)==0){
ptr->jumlah=new_quant;
ptr->harga=ptr->jumlah*starting_price;
count++;
break;
}
ptr=ptr->next;
}
if(count!=-1){
printf("\t\tUpdated Your New Quants!!\n");
}
}

void popHead(){
if(head == tail){
head = tail = NULL;
free(head); 
free(tail);
} else {
node *ptr = head->next;
head->next = ptr->prev = NULL;
free(head);
head = ptr;
}
}

void popTail(){
if(head == tail){
head = tail = NULL;
free(head); 
free(tail);
} else {
node *ptr = head;
while(ptr){
if(ptr->next == tail){
ptr->next = NULL;
tail->prev = NULL;
free(tail);
tail = ptr;
break;
}
ptr = ptr->next;
}
}
}

void popMid(char *words){
node *ptr = head;
while(ptr->next != NULL){
if(strcmp(ptr->next->listed,words)==0){
ptr->next->next->prev = ptr;
ptr->next = ptr->next->next;
ptr->next->prev = ptr;
}
ptr = ptr->next;
}
}

void popping(char *words){
node *ptr=head;
while(ptr!=NULL){
if(strcmp(ptr->listed,words)==0){
if(ptr==head){
popHead();
} else if(ptr==tail){
popTail();
} else {
popMid(words);
}
break;
}
ptr=ptr->next;
}
}

void checkOut(){
if(head==NULL){
printf("MASIH KOSONG NIH :(\n");
} else {
int tot=0,quants=0;
node *curr;
while(head!=NULL){
tot+=head->jumlah;
quants+=head->harga;
curr=head;
head=head->next;
free(curr);
}
puts("Here's Your Final Shopping Lists !");
int t_mov; double t_mos;
  char alphabet1[]="TELOLELOLET ------============================";
  char alphabet2[]="Struk Pembelanjaan sedang diprint!============";
  char alphabet3[]="Mohon ditunggu sebentar ya!===================";
       printf("\n\n");
    for(t_mov=0; alphabet1[t_mov]!=NULL; t_mov++)
  {
    printf("%c",alphabet1[t_mov]);
      for(t_mos=0; t_mos<=7777777; t_mos++)
      {
      }
  }
  printf("\n\n");
    for(t_mov=0; alphabet2[t_mov]!=NULL; t_mov++)
  {
    printf("%c",alphabet2[t_mov]);
      for(t_mos=0; t_mos<=7777777; t_mos++)
    {
      }
  }
  printf("\n\n");
       for(t_mov=0; alphabet3[t_mov]!=NULL; t_mov++)
        {
      printf("%c",alphabet3[t_mov]);
      for(t_mos=0; t_mos<=7777777; t_mos++)
          {
               }
          }
        printf("\n\n");
printf("Total Items : %d\n",tot);
printf("Total Costs : Rp %llu,-\n",quants);
}
}


void ShopMenu(){
int tot=0,quants=0;
int opsi;
char jawaban;
do{
puts("11111111111111111111111111111111¶¶¶¶¶1");
puts("1111111111111111111111111111111¶1__1¶¶¶"); 
puts("111111111111111111111111111111¶1_____1¶¶"); 
puts("11111111111111111111111111111¶1_111___1¶¶"); 
puts("1111111111111111111111111111¶1_1¶¶¶11_1¶¶");
puts("111111111111111111111111111¶1___1¶¶¶¶_1¶¶");
puts("11111111111111111111111111¶1______1¶¶_1¶¶"); 
puts("1111111111111111111111111¶¶¶11______1_¶¶¶¶¶¶¶");
puts("11111111111111¶111111111¶¶¶¶¶111______¶¶¶¶¶¶¶");
puts("1111111111111¶¶¶1111111¶¶___¶¶¶11______1¶¶¶¶¶");
puts("11111111111¶¶¶¶¶¶11111¶¶_____1¶¶¶11______1¶¶ ");
puts("1111111111¶¶___¶¶1111¶¶11______¶¶¶¶11___1¶¶¶"); 
puts("111111111¶¶____1¶¶11¶¶¶¶111______¶¶¶11_1¶¶¶"); 
puts("11111111¶¶______1¶¶¶1_1¶¶111______1¶¶¶1¶¶¶");
puts("1111111¶¶________1¶1____¶¶¶111______11¶¶¶"); 
puts("111111¶¶________11_______1¶¶¶11______¶¶¶"); 
puts("11111¶¶_________1¶¶1_______¶¶¶¶¶___1¶¶¶"); 
puts("1111¶¶__________¶¶¶¶¶1_______¶¶1_¶1¶¶¶"); 
puts("111¶¶1_________1¶¶¶¶¶¶¶1_________1¶¶¶"); 
puts("11¶¶1______¶¶1_1¶¶¶¶¶¶¶¶1________1¶¶"); 
puts("1¶¶1______¶¶¶¶_1¶¶¶¶¶¶¶¶¶¶1_____¶¶¶¶"); 
puts("1¶¶______¶¶¶1¶¶_1¶¶¶¶¶¶¶¶¶¶¶111¶¶¶¶¶");
puts("1¶¶_____¶¶¶111¶¶1¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶"); 
puts("1¶¶____1¶¶11111¶¶_1¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶"); 
puts("11¶¶___¶¶1111111¶¶_11¶¶¶¶¶¶¶¶¶¶¶¶"); 
puts("111¶¶_1¶¶11111111¶¶____¶¶¶¶¶¶¶"); 
puts("1111¶¶1¶¶111111111¶¶_______¶¶¶¶"); 
puts("11111¶¶¶1111111111¶¶________¶¶¶¶"); 
puts("111111¶¶11111111111¶¶_________¶¶¶¶¶"); 
puts("11111111111111111111¶¶__________¶¶¶");
puts("111111111111111111111¶¶________¶¶¶"); 
puts("1111111111111111111111¶¶______¶¶¶"); 
puts("1111111111111111111111¶¶_____¶¶¶"); 
puts("11111111111111111111111¶¶___¶¶¶"); 
puts("111111111111111111111111¶¶_¶¶¶"); 
puts("1111111111111111111111111¶¶¶¶");
printf("\n\n");
puts("******************************");
puts("|----------------------------|");
puts("| COVIDIAN'S SEVEN-UP SHOPS! |");
puts("|----------------------------|");
puts("******************************");
puts("1. Buy Something!");
puts("2. Update Your Stuff Lists");
puts("3. Delete Your Stuff");
puts("4. Check Out");

printf("\n\n\n");
printf("Current List :\n");
printf("***********************\n");

if(head==NULL){
puts("Still Empty like your HEART.");
}
else{
node *curr=head;
unsigned long long int pricings=0;
while(curr!=NULL){
quants+=curr->jumlah;
pricings+=curr->harga;
printf("%d) - ITEM  : %s\n",++tot,curr->listed);
printf("   - JUMLAH ITEM  : %d\n",curr->jumlah);
printf("   - HARGA ITEM : %llu\n\n",curr->harga);
curr=curr->next;
}
printf("\n");
puts("|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|");
printf("TOTAL PRICE ITEM LIST : %llu\n",pricings);
puts("===============================");
}

printf("\n\n");
printf("PILIHAN : ");
scanf("%d",&opsi);
do{
if(opsi==1){
char item_name[109];
int item_quant;
printf("Masukkan Nama Barang : "); getchar();
scanf("%[^\n]",item_name);
printf("Masukkan Jumlah Barang : ");
scanf("%d",&item_quant);
push(item_name,item_quant);
break;
}
if(opsi==2){
char updating[109];
int new_quant;
if(head!=NULL){
printf("Nama Barang Yang Mau di-Update : "); getchar();
scanf("%[^\n]",updating);
printf("Jumlah barang yang baru : ");
scanf("%d",&new_quant);
update(updating,new_quant);
break;
} else {
printf("Mau Update Item yang mana woi.\n");
break;
}
}
if(opsi==3){
char remov_item[109];
if(head!=NULL){
printf("NAME ITEM YANG AKAN DI REMOVE: "); getchar();
scanf("%[^\n]",remov_item);
popping(remov_item);
break;
}else{
printf("Belum ada barang yang Anda beli. \n");
break;
}
}
if(opsi==4){
printf("CHECKOUT LIST\n");
checkOut();
printf("Bye have a good time\n");
}
}while(opsi>=1 && opsi<=4);
if(opsi>=4){
printf("You think there'll be heap exploitation? Hmm idk either :p!\n");
}

printf("Lakukan transaksi lainnya? [Y/N](Case-sensitive)\n");
printf("Jawab : ");
scanf("%s",&jawaban);

}while(jawaban=='Y');

}

int main(){
srand(time(NULL));
head = tail = NULL;
ShopMenu();
return 0;
}










Sumber :

https://www.mahirkoding.com/struktur-data-single-linked-list-dengan-bahasa-c/


Comments