Quadratic Probing in Hashing (original) (raw)
Hashing is an improvement technique over the Direct Access Table. The idea is to use a hash function that converts a given number or any other key to a smaller number and uses the small number as the index in a table called a hash table.
**Quadratic Probing:
Quadratic probing is an open-addressing scheme where we look for the i2'th slot in the i'th iteration if the given hash value x collides in the hash table. We have already discussed linear probing implementation.
**How Quadratic Probing is done?
Let hash(x) be the slot index computed using the hash function.
- If the slot hash(x) % S is full, then we try (hash(x) + 1*1) % S.
- If (hash(x) + 1*1) % S is also full, then we try (hash(x) + 2*2) % S.
- If (hash(x) + 2*2) % S is also full, then we try (hash(x) + 3*3) % S.
- This process is repeated for all the values of i until an empty slot is found.
**Example:
Let us consider a simple hash function as “key mod 7” and sequence of keys as 22, 30 and 50.
Below is the implementation of the above approach:
C++ `
#include #include using namespace std;
void quadProbing(vector& table, int tsize, vector& arr) { int n = arr.size();
for (int i = 0; i < n; i++) {
// Hash function
int hv = arr[i] % tsize;
if (table[hv] == -1) {
// Place directly if slot is empty
table[hv] = arr[i] ;
}
else {
// Quadratic probing in case of collision
for (int j = 1; j <= tsize; j++) {
// Compute new index using quadratic probing
int t = (hv + j * j) % tsize;
// Place element if new slot is empty
if (table[t] == -1) {
table[t] = arr[i];
break;
}
}
}
}}
int main() { vector arr = { 50, 700, 76, 85, 92, 73, 101 };
int tsize = 11 ;
vector<int> table(tsize, -1) ;
quadProbing(table, tsize, arr) ;
for (int i = 0; i < table.size(); i++) {
cout << table[i] << " ";
}
return 0;}
Java
import java.util.Arrays;
public class GfG { static void quadProbing(int[] table, int tsize, int[] arr) {
int n = arr.length;
for (int i = 0; i < n; i++) {
// Hash function
int hv = arr[i] % tsize;
// Place directly if slot is empty
if (table[hv] == -1)
table[hv] = arr[i];
else {
// Quadratic probing in case of collision
for (int j = 1; j <= tsize; j++) {
// Compute new index using quadratic probing
int t = (hv + j * j) % tsize;
// Place element if new slot is empty
if (table[t] == -1) {
table[t] = arr[i];
break;
}
}
}
}
}
public static void main(String[] args) {
int[] arr = { 50, 700, 76, 85, 92, 73, 101 };
int tsize = 11;
int[] table = new int[tsize];
Arrays.fill(table, -1);
quadProbing(table, tsize, arr);
for (int val : table) {
System.out.print(val + " ");
}
}}
Python
def quadProbing(table, tsize, arr): n = len(arr)
for i in range(n):
# Hash function
hv = arr[i] % tsize
# Place directly if slot is empty
if table[hv] == -1:
table[hv] = arr[i]
else:
# Quadratic probing in case of collision
for j in range(1, tsize + 1):
# Compute new index using quadratic probing
t = (hv + j * j) % tsize
# Place element if new slot is empty
if table[t] == -1:
table[t] = arr[i]
breakif name == "main": arr = [50, 700, 76, 85, 92, 73, 101] tsize = 11 table = [-1] * tsize quadProbing(table, tsize, arr) print(" ".join(map(str, table)))
C#
using System;
class GfG { static void QuadProbing(int[] table, int tsize, int[] arr) {
// Get number of elements to insert
int n = arr.Length;
for (int i = 0; i < n; i++) {
// Hash function
int hv = arr[i] % tsize;
// Place directly if slot is empty
if (table[hv] == -1)
table[hv] = arr[i];
else {
// Quadratic probing in case of collision
for (int j = 1; j <= tsize; j++) {
// Compute new index using quadratic probing
int t = (hv + j * j) % tsize;
// Place element if new slot is empty
if (table[t] == -1) {
table[t] = arr[i];
break;
}
}
}
}
}
static void Main() {
int[] arr = { 50, 700, 76, 85, 92, 73, 101 };
int tsize = 11;
int[] table = new int[tsize];
for (int i = 0; i < tsize; i++) table[i] = -1;
QuadProbing(table, tsize, arr);
foreach (int val in table) {
Console.Write(val + " ");
}
}}
JavaScript
function quadProbing(table, tsize, arr) {
let n = arr.length;
for (let i = 0; i < n; i++) {
// Hash function
let hv = arr[i] % tsize;
// Place directly if slot is empty
if (table[hv] === -1)
table[hv] = arr[i];
else {
// Quadratic probing in case of collision
for (let j = 1; j <= tsize; j++) {
// Compute new index using quadratic probing
let t = (hv + j * j) % tsize;
// Place element if new slot is empty
if (table[t] === -1) {
table[t] = arr[i];
break;
}
}
}
}}
// Driver Code let arr = [50, 700, 76, 85, 92, 73, 101]; let tsize = 11; let table = new Array(tsize).fill(-1); quadProbing(table, tsize, arr); console.log(table.join(" "));
`
Output
73 -1 101 -1 92 -1 50 700 85 -1 76
**Time Complexity: O(n * l), where n is the length of the array and l is the size of the hash table.
**Auxiliary Space: O(1)
The above implementation of quadratic probing does not guarantee that we will always be able to use a hash table empty slot. It might happen that some entries do not get a slot even if there is a slot available.
Let's consider the input array [21, 10, 32, 43, 54, 65, 87, 76] and table size 11, we get the output as [10, -1, 65, 32, 54, -1, -1, -1, 43, -1, 21] which means the items 87 and 76 never get a slot. To make sure that elements get filled, we need to have a higher table size.
A hash table can be fully utilized using the below idea.
Iterate over the hash table to next power of 2 of table size. For example if table size is 11, then iterate 16 times. And iterate over the hash table using the below formula
hash(x) = [hash(x) + (j + j*j)/2] % (Next power of 2 of table size)
C++ `
#include #include using namespace std;
// Function to compute the next // power of 2 greater than or equal to m int nextPowerOf2(int m) { m-- ; m |= m >> 1 ; m |= m >> 2 ; m |= m >> 4 ; m |= m >> 8 ; m |= m >> 16 ; m |= m >> 32 ; m++ ; return m ; }
void quadProbing(vector& table, int tsize, vector& arr) {
// Get number of elements to insert
int n = arr.size();
for (int i = 0; i < n; i++) {
// Hash function
int hv = arr[i] % tsize;
// Place directly if slot is empty
if (table[hv] == -1) {
table[hv] = arr[i];
}
else {
int m = nextPowerOf2(tsize) ;
// Perform modified quadratic probing
for (int j = 1; j <= m; j++) {
// Compute new index using the
// custom probing formula
int t = (hv + (j + j * j) / 2) % m;
// Skip if out of bounds for original table size
if (t >= tsize)
continue ;
// Place element if slot is empty
if (table[t] == -1) {
table[t] = arr[i];
break ;
}
}
}
}}
int main() { vector arr = { 21, 10, 32, 43, 54, 65, 87, 76 }; int tsize = 11; vector table(tsize, -1); quadProbing(table, tsize, arr);
for (int i = 0; i < table.size(); i++) {
cout << table[i] << " ";
}
cout << endl;
return 0;}
Java
import java.util.Arrays;
public class GfG {
// Function to compute the next power
// of 2 greater than or equal to m
static int nextPowerOf2(int m) {
m--;
m |= m >> 1;
m |= m >> 2;
m |= m >> 4;
m |= m >> 8;
m |= m >> 16;
m++;
return m ;
}
static void quadProbing(int[] table, int tsize, int[] arr) {
int n = arr.length ;
for (int i = 0; i < n; i++) {
// Hash function
int hv = arr[i] % tsize;
// Place directly if slot is empty
if (table[hv] == -1) {
table[hv] = arr[i];
} else {
// Compute the next power
// of 2 greater than tsize
int m = nextPowerOf2(tsize);
// Perform modified quadratic probing
for (int j = 1; j <= m; j++) {
// Compute new index using the
// custom probing formula
int t = (hv + (j + j * j) / 2) % m;
// Skip if out of bounds for original table size
if (t >= tsize)
continue;
// Place element if slot is empty
if (table[t] == -1) {
table[t] = arr[i] ;
break ;
}
}
}
}
}
public static void main(String[] args) {
int[] arr = {21, 10, 32, 43, 54, 65, 87, 76};
int tsize = 11;
int[] table = new int[tsize];
Arrays.fill(table, -1);
quadProbing(table, tsize, arr);
for (int val : table) {
System.out.print(val + " ");
}
System.out.println();
}}
Python
Function to compute the next power
of 2 greater than or equal to m
def nextPowerOf2(m): m -= 1 m |= m >> 1 m |= m >> 2 m |= m >> 4 m |= m >> 8 m |= m >> 16 m += 1 return m
Function to perform modified quadratic probing
def quadProbing(table, tsize, arr):
n = len(arr)
for i in range(n):
# Hash function
hv = arr[i] % tsize
# Place directly if slot is empty
if table[hv] == -1:
table[hv] = arr[i]
else:
# Compute the next power of 2 greater than tsize
m = nextPowerOf2(tsize)
# Perform modified quadratic probing
for j in range(1, m + 1):
# Compute new index using the custom probing formula
t = (hv + (j + j * j) // 2) % m
# Skip if out of bounds for original table size
if t >= tsize:
continue
# Place element if slot is empty
if table[t] == -1:
table[t] = arr[i]
breakif name == "main": arr = [21, 10, 32, 43, 54, 65, 87, 76] tsize = 11 table = [-1] * tsize quadProbing(table, tsize, arr) print(" ".join(map(str, table)))
C#
using System;
class GfG { // Function to compute the next power of 2 greater than or equal to m static int NextPowerOf2(int m) { m--; m |= m >> 1; m |= m >> 2; m |= m >> 4; m |= m >> 8; m |= m >> 16; m++; return m; }
// Function to perform modified quadratic probing
static void quadProbing(int[] table, int tsize, int[] arr) {
int n = arr.Length;
for (int i = 0; i < n; i++) {
// Hash function
int hv = arr[i] % tsize;
// Place directly if slot is empty
if (table[hv] == -1) {
table[hv] = arr[i];
} else {
// Compute the next power of 2 greater than tsize
int m = NextPowerOf2(tsize);
// Perform modified quadratic probing
for (int j = 1; j <= m; j++) {
// Compute new index using the custom probing formula
int t = (hv + (j + j * j) / 2) % m;
// Skip if out of bounds for original table size
if (t >= tsize)
continue;
if (table[t] == -1) {
table[t] = arr[i];
break;
}
}
}
}
}
static void Main() {
int[] arr = { 21, 10, 32, 43, 54, 65, 87, 76 };
int tsize = 11;
int[] table = new int[tsize];
for (int i = 0; i < tsize; i++) table[i] = -1;
quadProbing(table, tsize, arr);
foreach (int val in table) {
Console.Write(val + " ");
}
Console.WriteLine();
}}
JavaScript
// Function to compute the next power of 2 greater than or equal to m function nextPowerOf2(m) { m--; m |= m >> 1; m |= m >> 2; m |= m >> 4; m |= m >> 8; m |= m >> 16; m++; return m; }
// Function to perform modified quadratic probing function quadProbing(table, tsize, arr) {
let n = arr.length;
for (let i = 0; i < n; i++) {
// Hash function
let hv = arr[i] % tsize;
// Place directly if slot is empty
if (table[hv] === -1) {
table[hv] = arr[i];
} else {
// Compute the next power of 2 greater than tsize
let m = nextPowerOf2(tsize);
// Perform modified quadratic probing
for (let j = 1; j <= m; j++) {
// Compute new index using the custom probing formula
let t = (hv + Math.floor((j + j * j) / 2)) % m;
// Skip if out of bounds for original table size
if (t >= tsize)
continue;
// Place element if slot is empty
if (table[t] === -1) {
table[t] = arr[i];
break;
}
}
}
}}
// Driver Code let arr = [21, 10, 32, 43, 54, 65, 87, 76]; let tsize = 11; let table = new Array(tsize).fill(-1); quadProbing(table, tsize, arr); console.log(table.join(" "));
`
Output
10 87 -1 -1 32 -1 54 65 76 43 21
**Time Complexity: O(n * l), where n is the length of the array and l is the size of the hash table.
**Auxiliary Space: O(1)