Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/**
* @file quadratic_probing.cpp
* @brief Implementasi metode Quadratic Probing untuk menangani tabrakan
* (collision) pada hash table.
*
* # Deskripsi (Description)
* Menambahkan program salah satu metode untuk menangani tabrakan pada hash
* table dengan teknik *open addressing*, yaitu **Quadratic Probing**.
*
* Pada metode ini, jika terjadi tabrakan di posisi hasil hash awal `h(k)`, maka
* posisi baru dihitung menggunakan fungsi kuadrat dari indeks percobaan (`i`):
*
*
* h(k, i) = (h(k) + i^2) % m
*
* di mana:
* - `h(k)` : hasil hash awal.
* - `i` : jumlah percobaan (0, 1, 2, 3, ...).
* - `m` : kapasitas tabel hash.
*
* Metode ini mengurangi kemungkinan *primary clustering* yang sering muncul
* pada *linear probing*.
* @note Quadratic probing memerlukan bahwa ukuran tabel (`m`) sebaiknya
* bilangan prima agar distribusi posisi hasil probing lebih merata.
*
* @see linear_probing.cpp untuk perbandingan metode linear probing.
*
*/
#include <cstddef>
#include <iostream>
class HashTable {
private:
enum Status { EMPTY, OCCUPIED, DELETED };

private:
/**
* @struct Entry
* @brief Struktur data untuk merepresentasikan satu slot (entri) pada hash
* table.
*
* Struktur `Entry` digunakan untuk menyimpan elemen pada tabel hash,
* sekaligus menandai status dari setiap slot (apakah kosong, terisi, atau
* dihapus) saat menggunakan metode *open addressing* seperti **Quadratic
* Probing**.
*
* ---
* @details Field (Anggota Data)
* - `int key`
* Menyimpan nilai kunci (key) yang akan dimasukkan ke dalam tabel hash.
* Nilai `key` digunakan dalam perhitungan fungsi hash.
*
* - `Status status`
* Menyimpan status dari entri:
* - `Status::EMPTY` → slot belum pernah terisi.
* - `Status::OCCUPIED` → slot saat ini terisi oleh sebuah kunci.
* - `Status::DELETED` → slot pernah terisi tapi sekarang kosong (dihapus),
* tetap dipertahankan agar probing tidak terputus.
*
* ---
*
*/
struct Entry {
int key;
Status status;
Entry() {
this->key = 0;
this->status = Status::EMPTY;
}
};

private:
std::size_t capacity;
std::size_t size;
Entry *table;
const int c1 = 1;
const int c2 = 1;

public:
HashTable() {
this->capacity = 8;
this->size = 0;
this->table = new Entry[capacity];
}
HashTable(std::size_t cap) {
this->capacity = cap;
this->size = 0;
this->table = new Entry[capacity];
}
HashTable(const HashTable &others) {
capacity = others.capacity;
size = others.capacity;
table = new Entry[capacity];
for (size_t i = 0; i < capacity; i++) {
table[i].key = others.table[i].key;
table[i].status = others.table[i].status;
}
}
~HashTable() { delete[] table; }

private:
int hash(std::size_t key) { return key % capacity; }

public:
double load_factor() { return static_cast<double>(size) / capacity; }

public:
bool insert(int key) {
std::size_t index = hash(key);
std::size_t i = 0;
while (i < capacity) {
std::size_t new_index = (index + c1 * i + c2 * i * i) % capacity;
if (table[new_index].status == Status::EMPTY ||
table[new_index].status == Status::DELETED) {
table[new_index].key = key;
table[new_index].status = Status::OCCUPIED;
return true;
}
i++;
}
return false;
}
bool search(int key) {
std::size_t index = hash(key);
std::size_t i = 0;
while (i < capacity) {
std::size_t new_index = (index + c1 * i + c2 * i * i) % capacity;
if (table[new_index].status == Status::EMPTY &&
table[new_index].status != Status::DELETED) {
return false;
}
if (table[new_index].status == Status::OCCUPIED &&
table[new_index].key == key) {
return true;
}
i++;
}
return false;
}
bool remove(int key) {
std::size_t index = hash(key);
return false;
std::size_t i = 0;
while (i < capacity) {
std::size_t new_index = (index + c1 * i + c2 * i * i) % capacity;
if (table[new_index].status == Status::OCCUPIED &&
table[new_index].key == key) {
table[new_index].key = 0;
table[new_index].status = Status::DELETED;
}
i++;
}
}

public:
void print() {
for (size_t i = 0; i < capacity; i++) {
std::cout << i << ": ";
if (table[i].status == OCCUPIED) {
std::cout << table[i].key << std::endl;
} else {
std::cout << "[x]" << std::endl;
}
}
}
};
int main() {
HashTable hash(10);
hash.insert(7);
hash.insert(13);
hash.insert(15);
hash.insert(1);
hash.insert(10);
hash.print();
std::cin.get();
return 0;
}
46 changes: 46 additions & 0 deletions struktur_data/hash_table/open_adressing/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,49 @@ Dimana:
5. Ulangi langkah 3 sampai menemukan slot kosong atau tabel penuh

Salah satu implementasi Linear Probing dapat digunakan pada hash function: [division_method.cpp](struktur_data/hash_table/hash_table.cpp)

### Quadratic Probing
**Quadratic Probing** adalah salah satu metode penanganan collision pada `hash table` untuk menangani **collision (tabrakan)**

Jika sebuah slot index hash penuh, maka algoritma akan mencari slot kosong menggunakan **fungsi kuadrat** terhadap jumlah percobaan `probe`

Rumus **Quadratic probing**
```math
h(k) = (h(k) + c1 * i + c2 *i * i) \bmod \text{capacity}
```

dimana:

`h(k)` = index hash

`i` = jumlah percobaan(probe) ke -i

`c1,c2` = kostanta(biasanya `c1 = c2 = 1`)

`capacity` = kapasitas hash table(banyak bucket)

**Langkah-langkah Quadratic Probing**
1.Gunakan fungsi hash untuk mendapatkan posisi awal
```math
h(k) = key \bmod \text{capacity}
```
2.periksa apakah slot kosong

- jika posisi h(k) kosong -> simpan data disitu

- jika sudah terisi lanjut ke langkah berikutnya

3.Gunakan fungsi kuadrat untuk mencari posisi baru
saat terjadi `collision` ke-i,hitung posisi baru:
```math
h(k) = (h(k) + c1 * i + c2 *i * i) \bmod \text{capacity}
```
4.cek apakah slot hasil probing kosong

- jika posisi h(k) kosong -> simpan data disitu

- jika sudah terisi ->increment i(i++)

5.berhenti jika ditemukan posisi kosong atau table penuh

Salah satu implementasi Quadratic Probing dapat digunakan pada hash function: [Quadratic Probing.cpp](struktur_data/hash_table/open_adressing/quadratic_probing/division_method.cpp)
Loading