Skip to content

Modul 7 Struktur Data

Zulkarnaen edited this page Aug 22, 2025 · 1 revision

Daftar Isi

Pengantar Struktur Data

Struktur data merupakan tata cara untuk merepresentasikan dan menyimpan data, sehingga memungkinkan dilakukan operasi terhadap data tersebut dengan efisien. Struktur data merupakan hal yang sangat umum dan wajib untuk dikuasai mengingat banyak sekali kasus dalam kehidupan nyata dapat diselesaikan dengan menggunakan pendekatan struktur data. Sebagai contoh, ketika sedang memesan sebuah makanan di restoran, kita perlu mengantri jika terdapat beberapa orang sebelumnya yang telah terlebih dahulu datang. Kasus ini merupakan salah satu contoh penerapan data Queue atau Antrian. Pendekatan ini dipilih karena suatu alasan, yakni pelanggan yang pertama datang adalah yang pertama juga untuk dilayani atau dikenal dengan konsep First Come First Serve.

Struktur data memiliki banyak sekali jenis, mulai dari yang sederhana hingga yang sangat kompleks. Pada modul ini, dijelaskan beberapa contoh struktur data sederhana beserta konsepnya, antara lain array, vector, stack, queue, heap, set, dan map. Masing-masing struktur data akan dijelaskan lebih rinci pada sub bab berikut.

Array

Tipe Array

Secara garis besar, array terbagi menjadi dua jenis yakni:

  • Static Array

    Static Array merupakan array yang memorinya dialokasikan pada saat kompilasi dengan ukuran yang tetap, sehingga kita tidak dapat mengubah atau memperbarui ukuran array.

  • Dynamic Array

    Dynamic Array merupakan array yang memorinya dialokasikan pada saat dijalankan namun tidak memiliki ukuran tetap. Dynamic array memungkinkan perubahan ukuran, baik bertambah maupun berkurang, mengikuti banyaknya data yang disimpan. Fitur ini merupakan sebuah keuntungan apabila kita tidak tahu berapa banyak elemen yang akan disimpan ke dalam array.

Deklarasi dan Inisialisasi Array

  • Deklarasi Array

    Deklarasi array merupakan aktivitas untuk membuat dan menyiapkan (deklarasi) suatu variabel yang akan dibuat sebuah array. Berikut adalah salah satu contoh deklarasi array yang paling sederhana.

    int arr[5];

    Pada contoh diatas, dilakukan inisialisasi array dengan nama arr dengan ukuran 5, yang berarti array dapat diisi dengan 5 elemen.

  • Insialisasi Array

    • Inisialisasi Array dengan Nilai

      int arr[5] = {1, 2, 3, 4, 5}
    • Inisialisasi Array dengan Nilai tanpa Ukuran

      int arr[] = {1, 2, 3, 4, 5}
    • Inisialisasi Array setelah deklarasi

      int ARRAY_SIZE = 5;
      int arr[ARRAY_SIZE];
      for (int i = 0; i < ARRAY_SIZE; i++) {
          arr[i] = i;
      }
    • Inisialisasi Array Parsial

      int arr[5] = {1, 2};
    • Inisialisasi Array dengan Seluruh Elemen bernilai 0

      Dengan menggunakan cara ini, seluruh elemen sebanyak ukuran array akan diisi dengan nilai didalam kurung kurawal.

      int arr[5] = {0};
    • Inisialisasi menggunakan class array yang ada pada C++11

      #include <iostream>
      #include <array>
      using namespace std;
      
      int main() {
        int ARRAY_SIZE = 4;
        array<int, ARRAY_SIZE> arr1;
        array<int, 5> arr2;
      }

Mengakses Nilai pada Array

Ketika kita mempunyai sebuah array dan ingin mengakses data atau elemen tertentu didalamnya, kita membutuhkan cara tertentu untuk mendapatkan nilainya. Pada array, dikenal istilah indeks yang merupakan semacam "identifier" untuk masing-masing elemen pada array. Indeks dimulai dari 0. Untuk mendapatkan nilai tertentu dari sebuah array kita perlu mengetahui indeks dari elemen yang ingin diambil.

int arr[4] = {10, 8, 7, 2}

Apabila kita memiliki array seperti contoh diatas, berarti kaitan indeks - value dari array tersebut adalah:

Indeks Value
0 10
1 8
2 7
3 2

Maka untuk mendapatkan nilai 7 pada array diatas dapat dilakukan dengan cara:

#include <iostream>
using namespace std;

int main() {
  int arr[4] = {10, 8, 7, 2};
  cout << arr[2];
}

Assign nilai ke dalam Array

Selain mendapatkan nilai di dalam array, kita juga dapat mengisi atau mengubah value pada indeks tertentu yang ada di dalam array.

 #include <iostream>
 using namespace std;

 int main() {
   int arr[4] = {10, 8, 7, 2};
   cout << "Nilai elemen pada indeks ke 2 sebelum diubah:" << arr[2] << endl;
   arr[2] = 9;
   cout << "Nilai elemen pada indeks ke 2 setelah diubah:" << arr[2] << endl;
 }

Output:

Nilai elemen pada indeks ke 2 sebelum diubah: 7
Nilai elemen pada indeks ke 2 setelah diubah: 9

Vector

Vector adalah sebuah array dinamis yang dapat menyesuaikan ukurannya sendiri. Tidak seperti array biasa yang ukurannya tetap, vector dapat bertambah atau berkurang ukurannya sesuai dengan elemen yang ditambahkan atau dihapus. Hal ini membuat vector sangat berguna ketika kita membutuhkan struktur data yang fleksibel seperti array di C++.

Deklarasi dan Inisialiasi Vector

Untuk mendeklarasikan dan menginisialisasi vector di C++, kita dapat menggunakan kelas vector dari Standard Template Library (STL).

#include <vector>
using namespace std;

int main()
{
   vector<tipe_data> vector_name // tipe_data bisa berupa int, char, string, dll
}

Selain itu, kita juga bisa menginisialisasi vector dengan ukuran tertentu atau daftar elemen yang kita inginkan.

vector<int> vec1(5); // Vector dengan ukuran 5
vector<int> vec2 = {1, 2, 3, 4, 5}; // Vector diinisialisasi dengan daftar nilai integer {1, 2, 3, 4, 5}

Operasi pada Vector

Selanjutnya yang tidak kalah penting adalah bagaimana mengoperasikan data yang disimpan kedalam vector. Terdapat beberapa fungsi yang berasosiasi dengan vector untuk mengoperasikan data, antara lain:

  • Push Back

    Fungsi push_back() digunakan untuk menambahkan elemen ke akhir vector.

     #include <vector>
     using namespace std;
    
     int main()
     {
         vector<int> vec;  // [ ]
         vec.push_back(1); // [1]
         vec.push_back(2); // [1, 2]
     }
  • Pop Back

    Fungsi pop_back() digunakan untuk menghapus elemen terakhir dari vector.

     #include <vector>
     using namespace std;
    
     int main()
     {
         vector<int>vec = {1, 2}; // [1, 2]
         vec.pop_back(); // [1]
     }
  • Size

    Fungsi size() digunakan untuk mengembalikan jumlah elemen di dalam vector.

     #include <iostream>
     #include <vector>
     using namespace std;
    
     int main()
     {
         vector<int>vec = {1, 2}; // [1, 2]
         cout << "Jumlah Elemen : " << vec.size(); 
     }

    Output

    Jumlah Elemen : 2
    
  • Empty

    Fungsi empty() digunakan untuk memeriksa apakah vector kosong (size = 0) atau tidak. Jika vector kosong maka fungsi akan mengembalikan nilai true dan false untuk kondisi sebaliknya.

      #include <iostream>
      #include <vector>
      using namespace std;
    
      int main()
      {
          vector<int>vec;
          cout << vec.empty();
      }

    Output

    1
    

    Output berisi 1 karena vector vec kosong.

  • Front

    Fungsi front() berguna untuk mendapatkan elemen paling depan dari vector.

      #include <iostream>
      #include <vector>
      using namespace std;
    
      int main()
      {
          vector<int>vec = {1, 2}; // [1, 2]
          cout << vec.front(); 
      }

    Output

    1
    

    Output berisi 1 karena data paling depan dari vector (indeks 0) bernilai 1.

  • Back

    Fungsi back() berguna untuk mendapatkan elemen paling akhir dari vector.

      #include <iostream>
      #include <vector>
      using namespace std;
    
      int main()
      {
          vector<int>vec = {1, 2}; // [1, 2]
          cout << vec.back(); 
      }

    Output

    2
    

    Output berisi 2 karena data paling akhir dari vector (indeks terakhir) bernilai 2.

  • Clear

    Fungsi clear() berguna untuk menghapus semua elemen di dalam vector. Pemanggilan fungsi vector ini akan mengakibatkan vector menjadi kosong.

      #include <vector>
      using namespace std;
    
      int main()
      {
          vector<int>vec = {1, 2}; // [1, 2]
          vec.clear();  // [ ] Vector sekarang kosong
      }

Aplikasi Vector

Vector sangat fleksibel dan dapat digunakan dalam berbagai aplikasi. Salagh satunya sebagai array dinamis yang bisa digunakan saat kita tidak mengetahui ukuran array yang dibutuhkan pada waktu kompilasi. Untuk informasi lebih lanjut mengenai vector pada C++, dapat dibaca di sini.

Stack

Stack adalah struktur data yang menyimpan data sesuai dengan namanya yakni tumpukan. Informasi terbaru akan disimpan ke posisi paling atas tumpukan. Informasi atau data yang dapat diakses atau dihapus adalah data yang berada pada posisi paling atas tumpukan. Maka daripada itu, stack memiliki konsep yang disebut dengan LIFO atau Last In First Out

image

Ilustrasi Struktur Data Stack

Deklarasi dan Inisialiasi Stack

Untuk melakukan deklarasi dan inisialisasi Stack di C++ cukup mudah dengan memanfaatkan standard library yang ada.

  stack<data_types> stack_name

Setelah diinisialisasi, stack akan kosong sebelum dilakukan operasi untuk menambah dan menghapus data kedalam stack.

Operasi pada Stack

Selain mengetahui konsep kerja dari stack dan mengetahui cara inisialisasi stack, selanjutnya yang tidak kalah penting adalah bagaimana mengoperasikan data yang disimpan kedalam stack. Terdapat beberapa fungsi yang berasosiasi dengan stack untuk mengoperasikan data, antara lain:

  • Push

    Push merupakan operasi yang digunakan untuk memasukkan atau menambahkan elemen baru ke posisi paling atas stack. Push membutuhkan satu argumen yangmana merupakan elemen yang akan ditambahkan ke dalam stack dan elemen yang ditambahkan harus memiliki tipe data yang sesuai dengan deklarasi stack.

    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main() {
      stack<int> s;	// []
      s.push(1);		// [1]
      s.push(2);		// [1, 2]
      s.push(3);		// [1, 2, 3]
    }
  • Pop

    Pop merupakan operasi yang digunakan untuk menghapus elemen baru dari posisi paling atas stack.

    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main() {
      stack<int> s;	// []
      s.push(1);		// [1]
      s.push(2);		// [1, 2]
      s.push(3);		// [1, 2, 3]
      s.pop();		// [1, 2]
      s.pop();		// [1]
      s.pop();		// []
    }
  • Top

    Top merupakan fungsi yang digunakan untuk mendapatkan elemen yang berada di posisi paling atas stack.

    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main() {
      stack<int> s;
      s.push(1);
      s.push(2);
      s.push(3);
      cout << s.top()
    }

    Output:

    3
    

    Output yang didapat adalah 3 karena 3 merupakan elemen terakhir yang ditambahkan sehingga berada di posisi paling atas stack. Kita tidak dapat menggunakan fungsi top apabila kondisi stack kosong, hal ini akan menyebabkan runtime error.

  • size

    Size merupakan fungsi yang digunakan untuk mendapatkan ukuran dari stack. Fungsi ini akan mengembalikan int yang merupakan jumlah elemen yang berada di dalam stack.

    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main() {
      stack<int> s;
      s.push(1);
      s.push(2);
      s.push(3);
      cout << s.size();
    }

    Output:

    3
    
  • empty

    empty adalah fungsi yang digunakan untuk mengecek apakah suatu stack kosong atau tidak. Fungsi ini akan mengembalikan boolean, true jika stack kosong atau tidak memiliki elemen, false jika sebaliknya.

    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main() {
      stack<int> s1, s2;
      s1.push(1);
      s1.push(2);
      cout << "isEmpty Stack 1 : " << s1.empty() << endl;
      cout << "isEmpty Stack 2 : " << s2.empty() << endl;
    }

    Output:

    isEmpty Stack 1 : 0
    isEmpty Stack 2 : 1
    

Aplikasi Stack

  • Fungsi rekursif

    Eksekusi fungsi rekursif dapat dilakukan menggunakan stack. Pemanggilan fungsi rekursif yang menambah kedalaman berarti melakukan push pada stack eksekusi fungsi. Fungsi yang akan dieksekusi adalah fungsi yang berada di posisi paling atas stack. Ketika fungsi paling atas selesai dieksekusi, dilakukan pop dan eksekusi dilanjutkan ke fungsi yang ada di tumpukan paling atas selanjutnya. Fungsi akan benar-benar selesai jika stack sudah kosong dan tidak ada lagi fungsi yang dieksekusi. Apabila terjadi pemanggilan fungsi rekursif yang terlalu dalam, hal ini dapat menimbulkan masalah yang kerap kali dikenal sebagai stack overflow.

  • Notasi postfix

    Stack dapat digunakan untuk kalkulator ekspresi matematika, khususnya dalam notasi postfix. Notasi postfix adalah notasi penulisan ekspresi matematika dengan urutan operand, operand, operator. Notasi ini digunakan oleh komputer karena komputer tidak dapat membedakan operator dan tanda kurung dengan mudah, sehingga akan sulit untuk dilakukan prioritas perhitungan. Dengan notasi ini komputer akan sangat mudah memproses ekspresi dari kiri ke kanan, meski ekspresi dinyatakan tanpa tanda kurung.

    Sebagai contoh, berikut adalah notasi postfix:

    1 2 3 + - 4 x yang berarti (1 - (2 + 3)) x 4
    

    Mekanisme pembacaan ekspresi postfix dengan menggunakan stack dijelaskan pada langkah-langkah berikut:

    1. Jika ditemukan operand, push ke dalam stack
    2. Jika ditemukan operator, pop dua kali untuk mendapatkan dua operand teratas kemudian kalkulasikan kedua operand dengan operator, dan push hasilnya ke dalam stack

    Pada contoh 1 2 3 + - 4 x, didapatkan hasil pembacaan ekspresi sebagai berikut:

    STACK EKSPRESI OPERASI KALKULASI
    [] Initial State
    [1] [1] 2 3 + - 4 x PUSH
    [1, 2] 1 [2] 3 + - 4 x PUSH
    [1, 2, 3] 1 2 [3] + - 4 x PUSH
    [1, 2] 1 2 3 [+] - 4 x POP
    [1] 1 2 3 [+] - 4 x POP 2 + 3 = 5
    [1, 5] 1 2 3 [+] - 4 x PUSH 5 (Hasil Kalkulasi)
    [1] 1 2 3 + [-] 4 x POP
    [] 1 2 3 + [-] 4 x POP 1 - 5 = -4
    [-4] 1 2 3 + [-] 4 x PUSH -4 (Hasil Kalkulasi)
    [-4, 4] 1 2 3 + - [4] x PUSH
    [-4] 1 2 3 + - 4 [x] POP
    [] 1 2 3 + - 4 [x] POP -4 x 4 = -16
    [-16] Final State PUSH -16 (HASIL AKHIR)

Queue

Queue adalah struktu data yang menyimpan informasi atau data dalam bentuk antrean. Data yang baru dimasukkan akan berada di posisi paling belakang antrean. Data yang akan diproses adalah data yang berada di posisi paling depan antrean atau data yang paling lama (paling awal) masuk ke antrean. Oleh karena itu, queue memiliki konsep FIFO atau First In First Out.

image

Ilustrasi Struktur Data Queue

Deklarasi dan Inisialisasi Queue

Deklarasi dan Inisialisasi Queue dapat dengan mudah dilakukan pada C++ dengan memanfaatkan Standard Template Library (STL).

#include <queue>
using namespace std;

int main () {
  queue<DATA_TYPES> queue_name;
}

Setelah di deklarasi, queue akan berisi elemen default sesuai tipe data masing-masing, misalnya jika queue berisi int maka nilai defaultnya adalah 0, jika char maka defaultnya adalah string kosong.

Operasi pada Queue

Terdapat beberapa fungsi yang dapat dimanfaatkan untuk melakukan operasi terhadap data yang ada di dalam queue. Beberapa operasi yang dapat dimanfaatkan antara lain:

  • push

    Push merupakan fungsi yang digunakan untuk menambahkan elemen ke posisi paling belakang antrean. Fungsi ini membutuhkan satu argumen yakni elemen yang akan di push ke dalam queue.

    #include <queue>
    using namespace std;
    
    int main () {
      queue<int> q1;
      q1.push(13);
      q1.push(9);
      q1.push(6); 
    }

    Setelah dilakukan push seperti kode diatas, maka kondisi queue terkini menjadi

    q1: [13, 9, 6]
    
  • pop

    Pop adalah fungsi yang digunakan untuk menghapus elemen yang berada di posisi terdepan antrean.

    #include <queue>
    using namespace std;
    
    int main () {
      queue<int> q1;
      q1.push(13);
      q1.push(9);
      q1.push(6);
      q1.pop();
      q1.pop();
    }

    Pada contoh kode diatas, kondisi awal dan akhir dari queue adalah sebagai berikut:

    Setelah push elemen 6:  [13, 9, 6]
    Setelah 2 kali pop:     [6]
    
  • empty

    Empty merupakan fungsi yang digunakan untuk mengecek apakah queue kosong atau tidak. Fungsi ini akan mengembalikan boolean, true jika queue dalam kondisi kosong, dan false jika sebaliknya.

    #include <queue>
    using namespace std;
    
    int main () {
      queue<int> q1;
      q1.empty(); // true
      q1.push(2);
      q1.empty(); // false
    }
  • size

    Size merupakan fungsi untuk mendapatkan ukuran dari queue atau jumlah elemen yang terdapat didalam queue. Fungsi ini mengembalikan integer yang menyatakan jumlah elemen.

    #include <queue>
    using namespace std;
    
    int main () {
      queue<int> q1;
      q1.size(); // 0
      q1.push(2);
      q1.size(); // 1
    }
  • front

    Front merupakan fungsi yang digunakan untuk mendapatkan nilai dari elemen yang berada di posisi paling depan antrean.

    #include <queue>
    using namespace std;
    
    int main () {
      queue<int> q1;
      q1.push(13);
      q1.push(9);
      q1.push(6);
      q1.front(); // 13
    }

    Output yang didapatkan adalah 13 karena angka 13 adalah elemen yang di input pertama kedalam queue sehingga berada di posisi terdepan.

  • back

    Back merupakan fungsi yang digunakan untuk mendapatkan nilai dari elemen yang berada di posisi paling belakang antrean.

    #include <queue>
    using namespace std;
    
    int main () {
      queue<int> q1;
      q1.push(13);
      q1.push(9);
      q1.push(6);
      q1.back(); // 6
    }

    Output yang didapatkan adalah 6 karena angka 6 adalah elemen yang di input terakhir kedalam queue sehingga berada di posisi paling belakang.

Heap

Heap adalah struktur data berbentuk pohon biner yang memenuhi sifat heap, di mana elemen pada setiap nodenya memiliki nilai yang lebih besar atau lebih kecil daripada elemen-elemen node pada anak-anaknya, tergantung pada jenis heap yang digunakan. Heap digunakan secara umum dalam implementasi priority queue.

Priority queue adalah struktur data yang mirip dengan queue biasa, namun dengan satu perbedaan utama: setiap elemen dalam priority queue memiliki prioritas yang menentukan urutan elemen tersebut saat dikeluarkan dari queue.

Deklarasi dan Inisialisasi

Untuk melakukan deklarasi priority queue, dalam C++ dapat dilakukan dengan mudah menggunakan Standard Template Library (STL) queue.

#include <queue>
using namespace std;

int main()
{
    priority_queue<tipe_data> nama_pq;
}

Setelah melakukan deklarasi seperti diatas, secara default priotiy queue berada dalam kondisi kosong. Untuk menambah atau menghapus data, kita bisa menggunakan operasi-operasi yang tersedia pada priority queue.

Operasi pada Priority Queue

Selanjutnya yang tidak kalah penting adalah bagaimana mengoperasikan data yang disimpan kedalam priority queue. Terdapat beberapa fungsi yang berasosiasi dengan priority queue untuk mengoperasikan data, antara lain:

  • push

    Operasi push berguna untuk menambahkan elemen / data kedalam priority queue.

     #include <queue>
     #include <iostream>
     using namespace std;
    
     int main()
     {
         priority_queue<int> pq;
         pq.push(10);
         pq.push(30);
         pq.push(20);
         pq.push(5);
    
         while (!pq.empty())
         {
             cout << pq.top() << " ";
             pq.pop();
         }
     }
    

    Output

    30 20 10 5 
    

    Secara default, priority_queue di C++ diimplementasikan sebagai max-heap. Ini berarti elemen terbesar akan selalu berada di posisi paling atas (root) dari heap. Untuk melakukan pengurutan secara terbalik dari kondisi defaultnya, kita bisa melakukan deklarasi prioirty queue seperti dibawah ini.

     #include <queue>
     #include <iostream>
     using namespace std;
    
     int main()
     { 
         priority_queue<int, vector<int>, greater<int>> pq;
         pq.push(10);
         pq.push(30);
         pq.push(20);
         pq.push(5);
    
         while (!pq.empty())
         {
             cout << pq.top() << " ";
             pq.pop();
         }
     }
    

    Output

    5 10 20 30
    
  • pop

    Operasi pop berguna untuk menghapus elemen dengan prioritas tertinggi dari priority queue.

     #include <queue>
     #include <iostream>
     using namespace std;
    
     int main()
     { 
         priority_queue<int> pq;
         pq.push(10);
         pq.pop();
         cout << pq.size() << endl;
     }

    Output

    0
    
  • top

    Operasi top memiliki fungsi untuk Mmngembalikan elemen dengan prioritas tertinggi tanpa menghapusnya.

     #include <queue>
     #include <iostream>
     using namespace std;
    
     int main()
     { 
         priority_queue<int> pq;
         pq.push(10);
         pq.push(30);
         cout << pq.top() << endl;
     }

    Output

    30
    
  • empty

    Operasi empty berguna untuk mengecek apakah priority queue kosong. Apabila priority queue kosong, maka fungsi empty() akan mengembalikan nilai True atau 1 dan mengembalikan nilai False atau 0 jika priority queue tidak kosong.

      #include <queue>
      #include <iostream>
      using namespace std;
    
      int main()
      { 
          priority_queue<int> pq;
          pq.push(10);
          pq.push(30);
          cout << pq.empty() << endl;
          pq.pop();
          pq.pop();
          cout << pq.empty() << endl;
      }

    Output

    0
    1
    
  • size

    Operasi size berguna untuk mengembalikan jumlah elemen / data yang ada di dalam priority queue.

      #include <queue>
      #include <iostream>
      using namespace std;
    
      int main()
      { 
          priority_queue<int> pq;
          pq.push(10);
          pq.push(30);
          cout << pq.size() << endl;
      }

    Output

    2
    

Aplikasi Priority Queue

Priority Queue adalah elemen kunci dalam algoritma Dijkstra, memungkinkan pemrosesan simpul dengan jarak terpendek secara efisien. Struktur ini menyimpan simpul-simpul dari graf dengan prioritas berdasarkan jarak terpendek yang diketahui dari simpul awal, sehingga simpul dengan jarak terkecil selalu diproses terlebih dahulu. Dengan menggunakan Priority Queue, algoritma Dijkstra dapat mengakses dan memperbarui simpul dengan waktu yang efisien, mengurangi jumlah operasi yang diperlukan dan memastikan bahwa jalur terpendek ditemukan dengan cepat. Tanpa Priority Queue, algoritma akan jauh lebih lambat dan kurang efisien. Detail mengenai algoritma Djisktra akan dipelajari di modul selanjutnya.

Set

Set merupakan struktur data yang merupakan kontainer berjenis asosiatif dimana setiap elemen harus memiliki nilai yang unik. Nilai-nilai yang disimpan ke dalam set diurutkan secara spesifik, baik dalam urutan naik (ascending) atau turun (descending).

Deklarasi dan Inisialisasi Set

Untuk melakukan deklarasi Set, dalam C++ dapat dilakukan dengan mudah menggunakan Standard Template Library (STL).

set<DATA_TYPES> SET_NAMES;

Setelah melakukan deklarasi, secara default Set berada dalam kondisi kosong. Untuk melakukan inisialisasi yang paling sederhana dapat dilakukan dengan cara berikut:

#include <iostream>
#include <set>
using namespace std;

int main(){
    set<int> angka;
    angka = {1, 2, 3, 4, 5};
}

atau secara langsung

#include <iostream>
#include <set>
using namespace std;

int main(){
    set<int> angka = {1, 2, 3, 4, 5};
}

Ciri Khas Set

Set memiliki beberapa ciri khas yang membedakannya dengan struktur data lainnya, antara lain:

  1. Penyimpanan elemen dalam Set disusun secara terurut (sorted). Secara default urutan penyimpanan elemen dalam Set disusun secara naik (ascending). Namun, kita dapat mengubah urutan penyimpanan elemen dalam Set sehingga menjadi turun (descending) dengan menggunakan kode ini saat deklarasi Set:

    set <data_type, greater<data_type>> set_name;
    
  2. Seluruh elemen yang disimpan ke dalam set adalah unik. Hal ini membuat struktur data set menghindari adanya elemen yang duplikat. Apabila terdapat elemen yang duplikat maka hanya akan disimpan satu saja elemen ke dalam set.

  3. Elemen atau nilai yang disimpan ke dalam set bersifat immutable, artinya ketika suatu nilai disimpan ke dalam set maka nilai tersebut tidak dapat dimodifikasi, namun tetap dapat untuk dihapus.

  4. Teknik pencarian dalam set mengimplementasikan teknik Binary Search Tree

  5. Elemen elemen yang disimpan ke dalam set tidak diindeks (unindexed).

Operasi dalam Set

Terdapat banyak sekali fungsi yang dapat dimanfaatkan untuk melakukan operasi terhadap data yang ada di dalam set. Beberapa operasi yang dapat dimanfaatkan antara lain:

  • begin dan end

    begin adalah fungsi yang digunakan untuk mengembalikan iterator yang menunjuk ke elemen pertama dari set. Sedangkan end mengembalikan iterator yang menunjuk ke elemen terakhir dari set. Kedua fungsi ini kerap kali digunakan untuk menelusuri seluruh bagian dalam set dan biasanya dipadukan dengan perulangan.

    #include <iostream>
    #include <set>
    using namespace std;
    
    int main(){
        set<int> angka = {1, 4, 2, 3, 5};
        for (auto it = angka.begin(); it != angka.end(); ++it)
            cout << ' ' << *it;
    }

    Output:

    1 2 3 4 5
    
  • size

    Size adalah fungsi yang digunakan untuk mendapatkan ukuran atau jumlah elemen yang berada di dalam set. Fungsi ini akan mengembalikan integer yang menyatakan jumlah elemen.

    #include <iostream>
    #include <set>
    using namespace std;
    
    int main(){
      set<int> angka = {1, 4, 2, 3, 5};
      cout << angka.size();
    }

    Output:

    5
    

    Apabila terdapat elemen yang duplikat maka hanya akan terhitung satu. Misalnya dari contoh diatas isi set nya adalah 1, 1, 2, 2, 4 maka size dari set tersebut adalah 3 yakni elemen 1, 2, dan 4.

  • max size

    Fungsi max size akan mengembalikan ukuran atau jumlah elemen maksimal yang dapat dimasukkan ke dalam set.

    #include <iostream>
    #include <set>
    using namespace std;
    
    int main(){
      set<int> angka = {1, 4, 2, 3, 5};
      cout << "Maximum size dari set angka diatas adalah : " << angka.max_size();
    }

    Output:

    Maximum size dari set angka diatas adalah : 461168601842738790
    
  • empty

    Empty digunakan untuk mengecek apakah suatu set kosong atau tidak. Fungsi ini mengembalikan boolena, true jika set kosong dan false jika sebaliknya.

    #include <iostream>
    #include <set>
    using namespace std;
    
    int main(){
      set<int> angka;
      cout << "Kondisi awal : " << angka.empty() << endl;
      angka = {1, 4, 2, 3, 5};
      cout << "Kondisi akhir : " << angka.empty();
    }

    Output:

    Kondisi awal : 1
    Kondisi akhir : 0
    
  • insert

    insert digunakan untuk menambahkan elemen baru ke dalam set. Fungsi insert dapat digunakan untuk menambahkan elemen baru secara langsung, atau menambahkan elemen ke posisi tertentu dengan mencantumkan posisi iterator. Berikut adalah pseudocode atau penulisan sintaksis untuk fungsi insert.

    Insert Elemen Baru Secara Langsung ke dalam Set
    iterator set_name.insert(element)
    
    Untuk Insert Elemen Pada Range Tertentu
    void set_name.insert(iterator position1, iterator position2) 
    

    Sebagai contoh, berikut adalah implementasi kedua metode insert secara sederhana:

    #include <bits/stdc++.h>
    using namespace std;
    
    int main(){
        set<int> s1;
        s1.insert(1);
        s1.insert(4);
        s1.insert(2);
        s1.insert(5);
        s1.insert(3);
    
        cout << "Elemen pada Set 1: ";
        for (auto it = s1.begin(); it != s1.end(); it++)
            cout << *it << " ";
    
        set<int> s2;
    
        s2.insert(s1.find(3), s1.end());
    
        cout << "\nElemen pada Set 2: ";
        for (auto it = s2.begin(); it != s2.end(); it++)
            cout << *it << " ";
    
    }

    Output:

    Elemen pada Set 1: 1 2 3 4 5 
    Elemen pada Set 2: 3 4 5 
    
  • erase

    Fungsi erase digunakan untuk menghapus elemen yang ada di dalam set. Fungsi erase juga terdapat beberapa variasi untuk menggunakannya, yakni menggunakan nilai dari elemen yang akan dihapus, posisi elemen yang akan dihapus, dan range posisi elemen apa saja yang akan dihapus. Perbedaan ini dinyatakan dari argumen yang diberikan saat pemanggilan fungsi ini. Berikut ini pseudocode atau penulisan sintaksis dari fungsi erase.

    setname.erase(position)
    setname.erase(startingposition, endingposition)
    setname.erase(value)
    

    Sebagai contoh, berikut ini adalah implementasi dari beberapa metode untuk menghapus elemen dalam set.

    • Hapus berdasarkan posisi

      #include <iostream>
      #include <set>
      
      using namespace std;
      
      int main(){
        set<int> angka{ 1, 2, 3, 4, 5 };
          set<int>::iterator it;
      
          it = angka.begin();
      
          it++;
      
          angka.erase(it);
          
          for (auto it = angka.begin();
              it != angka.end(); ++it)
              cout << ' ' << *it;
          
      }

      Output:

      1 3 4 5
      
    • Hapus elemen pada rentang tertentu

      #include <iostream>
      #include <set>
      
      using namespace std;
      
      int main(){
        set<int> angka{ 1, 2, 3, 4, 5 };
        set<int>::iterator it1, it2;
      
        it1 = angka.begin();
        it2 = angka.end();
      
        it1++;
        it1++;
      
        angka.erase(it1, it2);
          
        for (auto it = angka.begin(); it != angka.end(); ++it)
          cout << ' ' << *it;
      }

      Output:

      1 2
      
    • Menghapus Elemen berdasarkan Value

      #include <iostream>
      #include <set>
      #include <string>
      
      using namespace std;
      
      int main(){
      
        set<string> schematics{ "National", "Programming", "Contest", "2024" };
        schematics.erase("Programming");
        for (auto it = schematics.begin(); it != schematics.end(); ++it)
          cout << ' ' << *it;
          
      }

      Output:

      2024 Contest National
      
  • find

    find merupakan fungsi untuk melakukan pencarian ke dalam set yang mengembalikan iterator ke elemen dicari dalam set jika ditemukan, jika tidak, mengembalikan iterator ke akhir.

    #include <iostream>
    #include <set>
    
    using namespace std;
    
    int main(){
      set<int> s1{ 1, 4, 5, 2, 3 };
    
        auto lower_bound = s1.find(2); 
        
        for(auto it = lower_bound; it != s1.end(); ++it){
          cout << " " << *it;
        }
        
    }

    Output:

    2 3 4 5
    

    Output tersebut didapat karena pada batas bawah atau lower bound kita mencoba menemukan posisi atau iterator dari elemen 2. Elemen 2 berada pada posisi atau iterator kedua dalam set. Sehingga pada perulangan, iterasi dimulai dari posisi kedua yakni elemen bernilai 2.

  • clear

    Clear merupakan fungsi yang berfungsi untuk menghapus seluruh elemen pada set (mengosongkan set).

    #include <iostream>
    #include <set>
    
    using namespace std;
    
    int main(){
      set<int> s1{ 1, 4, 5, 2, 3 };
      s1.clear();
      cout << s1.empty();
    }

    Output:

    1
    

    Terlihat pada output muncul angka 1 atau true yang merupakan hasil pengecekan menggunakan fungsi empty setelah set di clear.

Map

Map adalah struktur data asosiatif dalam C++ yang menyimpan elemen-elemen dalam pasangan key-value. Key (kunci) digunakan untuk mengidentifikasi elemen secara unik, sedangkan value (nilai) adalah data yang terkait dengan kunci tersebut. Map menyediakan cara yang efisien untuk mencari, menambahkan, dan menghapus elemen berdasarkan kunci.

image

Ilustrasi Struktur Data Map

Deklarasi dan Inisialisasi Map

Dalam C++, map dapat dideklarasikan dengan menggunakan Standard Template Library (STL) sebagai berikut:

map<key_type, value_type> map_name;
  • key_type adalah tipe data dari kunci (key).
  • value_type adalah tipe data dari nilai (value).
  • map_name adalah nama dari map yang dideklarasikan.

Operasi dalam Map

Beberapa operasi yang umum dilakukan pada map termasuk:

  • insert

    Insert digunakan untuk menambahkan elemen baru ke dalam map. Jika kunci yang dimasukkan sudah ada, nilai yang terkait dengan kunci tersebut akan diperbarui.

    #include <iostream>
    #include <map>
    using namespace std;
    
    int main()
    {
        map<int, string> student;
        student.insert({1, "A"});
        student.insert({2, "B"});
    
        for (const auto &entry : student)
        {
            cout << entry.first << " : " << entry.second << endl;
        }
    
        // Menambahkan elemen dengan kunci yang sudah ada
        student[2] = "C";
    
        for (const auto &entry : student)
        {
            cout << entry.first << " : " << entry.second << endl;
        }
    }

    Output

    1 : A
    2 : C
  • erase

    Erase digunakan untuk menghapus elemen dari map berdasarkan kunci atau posisi iterator.

    #include <iostream>
    #include <map>
    using namespace std;
    
    int main() {
        map<int, string> student = {{1, "A"}, {2, "B"}, {3, "C"}};
    
        student.erase(2);  // Hapus elemen dengan kunci 2
    
        for (const auto &entry : student) {
            cout << entry.first << " : " << entry.second << endl;
        }
    }

    Output

    1 : A
    3 : C
    
  • find

    Find digunakan untuk mencari elemen dengan kunci tertentu dalam map. Jika ditemukan, fungsi ini mengembalikan iterator ke elemen yang sesuai; jika tidak, mengembalikan iterator ke end.

    #include <iostream>
    #include <map>
    using namespace std;
    
    int main() {
        map<int, string> student = {{1, "A"}, {2, "B"}, {3, "C"}};
    
        auto it = student.find(2);
        if (it != student.end()) {
            cout << "Ditemukan: " << it->first << " : " << it->second << endl;
        } else {
            cout << "Tidak ditemukan" << endl;
        }
    }

    Output

    Ditemukan: 2 : B
    
  • size

    Sesuai dengan namanya, size digunakan untuk mendapatkan jumlah elemen yang ada dalam map.

    #include <iostream>
    #include <map>
    using namespace std;
    
    int main() {
        map<int, string> student = {{1, "A"}, {2, "B"}, {3, "C"}};
        cout << "Total Elemen: " << student.size() << endl;
    }

    Output

    Total Elemen: 3
  • empty

    Empty digunakan untuk memeriksa apakah map kosong atau tidak. Fungsi ini mengembalikan true (1) jika kosong dan false (0) jika tidak.

     #include <iostream>
     #include <map>
     using namespace std;
    
     int main() {
         map<int, string> student;
         cout << "Kosong? " << student.empty() << endl;
    
         student[1] = "A";
         cout << "Kosong? " << student.empty() << endl;
     }

    Output

    Kosong? 1
    Kosong? 0
    
  • clear

    Clear digunakan untuk menghapus semua elemen dalam map, sehingga map menjadi kosong.

     #include <iostream>
     #include <map>
     using namespace std;
    
     int main() {
         map<int, string> student = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
         student.clear();
         cout << "Kosong? " << student.empty() << endl;
     }

    Output

    Kosong? 1
    

Aplikasi Map

Map di C++ memiliki banyak kegunaan, terutama ketika kita perlu menyimpan data yang memiliki hubungan satu-ke-satu, seperti dictionary, tabel hash, dan sebagainya. Penggunaan map yang lebih lanjut bisa melibatkan multimap untuk menyimpan beberapa nilai dengan kunci yang sama, atau menggunakan unordered_map untuk performa yang lebih cepat pada pencarian elemen.

Clone this wiki locally