Java Program for Pigeonhole Sort



In this article, we will learn Pigeonhole Sort in Java, a sorting algorithm designed for arrays with a small range of integer values. It organizes elements into "pigeonholes" based on their values and then reconstructs the sorted array. We'll discuss two approaches: a basic method using arrays and an optimized approach using LinkedLists.

What is Pigeonhole Sort?

Pigeonhole Sort works by distributing elements into a range of buckets based on their values. It is most effective when the range of input values is relatively small compared to the size of the dataset. The algorithm ensures stability and simplicity in sorting operations, making it a preferred choice for specific use cases.

Different approaches

The following are the two approaches for Pigeonhole sort in Java ?

Basic Pigeonhole Sort

The basic implementation creates an array of "holes" to hold frequency counts and reconstructs the sorted array based on these counts.

Arrays.fill() is a utility method in Java used to set all elements of an array to a specified value. It simplifies initializing or resetting array elements.

In the provided code, Arrays.fill() is used to initialize all elements of the sorted_arr ?

Arrays.fill(sorted_arr, 0);

following are the steps for Pigeonhole sort in Java ?

  • Finding the Range: Determine the minimum and maximum values to calculate the range of pigeonholes.
  • Creating Pigeonholes: Use an auxiliary array where each index represents a "hole" for input values.
  • Populating Holes: Map input values to the array by incrementing counts at corresponding indices.
  • Reconstructing the Array: Extract sorted values from the auxiliary array back into the original. 

Example

Following is an example of Pigeonhole sort in Java ?

import java.lang.*;
import java.util.*;
public class Demo {
   public static void pigeonhole_sorting(int my_arr[], int n) {
      int min_element = my_arr[0];
      int max_element = my_arr[0];
      int my_range, i, j, index;
      for(int a=0; a<n; a++) {
         if(my_arr[a] > max_element)
            max_element = my_arr[a];
         if(my_arr[a] < min_element)
            min_element = my_arr[a];
      }
      my_range = max_element - min_element + 1;
      int[] sorted_arr = new int[my_range];
      Arrays.fill(sorted_arr, 0);
      for(i = 0; i<n; i++)
         sorted_arr[my_arr[i] - min_element]++;
         index = 0;
      for(j = 0; j<my_range; j++)
         while(sorted_arr[j]-->0)
         my_arr[index++]=j+min_element;
   }
   public static void main(String[] args) {
      Demo my_instance = new Demo();
      int[] my_arr = {45, 67, 1, 20, 99, 74, 78};
      System.out.print("The array, after performing pigeonhole sorting is : ");
      my_instance.pigeonhole_sorting(my_arr,my_arr.length);
      for(int i=0 ; i<my_arr.length ; i++)
      System.out.print(my_arr[i] + " ");
   }
}

Output

The array, after performing pigeonhole sorting is : 1 20 45 67 74 78 99

Pigeonhole Sort with LinkedList

Instead of using a single-dimensional array for pigeonholes, we can use a LinkedList array to handle scenarios with duplicate values more efficiently.

  • A linked list is a linear data structure made up of nodes connected by pointers. Each node contains data and a pointer to the next node, with nodes stored at non-contiguous memory locations.
  • The add() method in Java's LinkedList class is used to add an element to the list. It handles inserting the new element at the correct position within the linked list.

Initialize Pigeonholes ?

List<Integer>[] holes = new LinkedList[range];
Arrays.setAll(holes, i -> new LinkedList<>());

Populate Pigeonholes ?

for (int num : arr) holes[num - min].add(num);

Reconstruct Sorted Array ?

for (List hole : holes) for (int num : hole) arr[index++] = num;

Example

Following is an example of Pigeonhole sort in Java ?

import java.util.*;

public class PigeonholeSortOptimized {
    public static void pigeonholeSort(int[] arr) {
        // Find the minimum and maximum values
        int min = Arrays.stream(arr).min().getAsInt();
        int max = Arrays.stream(arr).max().getAsInt();
        int range = max - min + 1;

        // Create pigeonholes as LinkedLists
        List<Integer>[] holes = new LinkedList[range];
        for (int i = 0; i < range; i++) {
            holes[i] = new LinkedList<>();
        }

        // Distribute elements into pigeonholes
        for (int num : arr) {
            holes[num - min].add(num);
        }

        // Collect elements from pigeonholes
        int index = 0;
        for (List<Integer> hole : holes) {
            for (int num : hole) {
                arr[index++] = num;
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {9, 3, 1, 7, 6, 5, 3, 2};
        System.out.println("Original Array: " + Arrays.toString(arr));
        pigeonholeSort(arr);
        System.out.println("Sorted Array: " + Arrays.toString(arr));
    }
}

Output

Original Array: [9, 3, 1, 7, 6, 5, 3, 2]  
Sorted Array: [1, 2, 3, 3, 5, 6, 7, 9]  

Comparison Table

Feature Basic Approach LinkedLists Approach
Time complexity O(n+range) O(n+range)

Space Complexity

O(range) O(range)
Handling Duplicates Simple frequency counting Uses LinkedLists for flexibility
Readability Easier to implement and understand Slightly more complex

Conclusion

Pigeonhole Sort is an excellent choice for sorting arrays with a narrow range of integer values. The basic approach is straightforward, while the optimized version adds flexibility for handling duplicates. By understanding both implementations, you can select the right approach based on your specific use case.

Alshifa Hasnain
Alshifa Hasnain

Converting Code to Clarity

Updated on: 2024-12-13T21:50:47+05:30

403 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements