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.

**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]
                break

if 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]
                break

if 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)