Bead Sort


Bead sort, also called gravity sort, is a natural sorting algorithm. Both digital and analog hardware implementations of bead sort can achieve a sorting time of O(n); however, the implementation of this algorithm tends to be significantly slower in software and can only be used to sort lists of positive integers. Also, it would seem that even in the best case, the algorithm requires O(n^2) space.

The bead sort operation can be compared to the manner in which beads slide on parallel poles, such as on an abacus. However, each pole may have a distinct number of beads. Initially, it may be helpful to imagine the beads suspended on vertical poles. In Step 1, put n rows of beads on m vertical poles from left to right, n is the length of the array to be sorted, m is the max num in the array.

If we then allow the beads to fall, the rows now represent the same integers in sorted order. Row 1 contains the largest number in the set, while row n contains the smallest.

Complexity

Bead sort can be implemented with four general levels of complexity, among others:

  • O(1): The beads are all moved simultaneously in the same time unit, as would be the case with the simple physical example above. This is an abstract complexity, and cannot be implemented in practice.
  • O(√N): In a realistic physical model that uses gravity, the time it takes to let the beads fall is proportional to the square root of the maximum height, which is proportional to n.
  • O(n): The beads are moved one row at a time. This is the case used in the analog and digital hardware solutions.
  • O(S), where S is the sum of the integers in the input set: Each bead is moved individually. This is the case when bead sort is implemented without a mechanism to assist in finding empty spaces below the beads, such as in software implementations.

Implementations

Implementation of Linear search algorithm in 5 languages that includes C, C++, Java, Python and Swift.

  • C
  • C++
  • Java
  • Python
  • Swift

C


  #include <stdio.h>
#include <stdlib.h>
// Part of Cosmos by OpenGenus Foundation
void bead_sort(int *a, int len)
{
    int i, j, max, sum;
    unsigned char *beads;
#   define BEAD(i, j) beads[i * max + j]
    for (i = 1, max = a[0]; i < len; i++)
        if (a[i] > max) max = a[i];
    beads = calloc(1, max * len);
    /* mark the beads */
    for (i = 0; i < len; i++)
        for (j = 0; j < a[i]; j++)
            BEAD(i, j) = 1;
    for (j = 0; j < max; j++) {
        /* count how many beads are on each post */
        for (sum = i = 0; i < len; i++) {
            sum += BEAD(i, j);
            BEAD(i, j) = 0;
        }
        /* mark bottom sum beads */
        for (i = len - sum; i < len; i++) BEAD(i, j) = 1;
    }
    for (i = 0; i < len; i++) {
        for (j = 0; j < max && BEAD(i, j); j++);
        a[i] = j;
    }
    free(beads);
}
int main()
{
    int i, x[] = {5, 3, 1, 7, 4, 1, 1, 20};
    int len = sizeof(x)/sizeof(x[0]);
    bead_sort(x, len);
    for (i = 0; i < len; i++)
        printf("%d\n", x[i]);
    return 0;
}

C++


  #include <vector>
#include <iostream>
using namespace std;
#define BEAD(i, j) beads[i * max + j]
// Part of Cosmos by OpenGenus Foundation
// function to perform the above algorithm
void beadSort(vector<int>& a)
{
    // Find the maximum element
    int max = a[0];
    for (size_t i = 1; i < a.size(); ++i)
        if (a[i] > max)
           max = a[i];
    // allocating memory
    vector<unsigned char> beads(max * a.size(), 0);
    // mark the beads
    for (size_t i = 0; i < a.size(); ++i)
        for (int j = 0; j < a[i]; ++j)
            BEAD(i, j) = 1;
    for (int j = 0; j < max; ++j)
    {
        // count how many beads are on each post
        int sum = 0;
        for (size_t i=0; i < a.size(); ++i)
        {
            sum += BEAD(i, j);
            BEAD(i, j) = 0;
        }
        // Move beads down
        for (size_t i = a.size() - sum; i < a.size(); ++i)
            BEAD(i, j) = 1;
    }
    // Put sorted values in array using beads
    for (size_t i = 0; i < a.size(); ++i)
    {
        int j;
        for (j = 0; j < max && BEAD(i, j); ++j);
    a[i] = j;
}

}
// driver function to test the algorithm
int main()
{
vector<int> a{5, 3, 1, 7, 4, 1, 1, 20};
beadSort(a);
cout<<"After Sorting.. "<<endl;
for (size_t i = 0; i < a.size(); ++i)
cout<<a[i]<<" ";
return 0;
}

Java


  import java.util.Arrays;
// Part of Cosmos by OpenGenus Foundation
public class BeadSort {
    private enum BeadSortStatus {
        MARKED,
        NOT_MARKED,
    }
    public static void main(String[] args) {
        int[] arrayToSort = new int[]{4, 1, 6, 2, 40, 5, 3, 8, 7};
        System.out.println(Arrays.toString(beadSort(arrayToSort)));
    }
    public static int[] beadSort(int[] arr) {
        int max = 0;
        for (int anArr : arr) {
            if (anArr > max) {
                max = anArr;
            }
        }
        //Set up abacus
        BeadSortStatus[][] grid = new BeadSortStatus[arr.length][max];
        int[] levelcount = new int[max];
        for(int i = 0; i < max; i++) {
            levelcount[i] = 0;
            for(int j = 0; j < arr.length; j++) {
                grid[j][i] = BeadSortStatus.NOT_MARKED;
            }
        }
        //Drop the beads
        for (int anArr : arr) {
            int num = anArr;
            for (int j = 0; num > 0; j++, num--) {
                grid[levelcount[j]++][j] = BeadSortStatus.MARKED;
            }
        }
        //Count the beads
        int[] sorted=new int[arr.length];
        for(int i = 0; i < arr.length; i++) {
            int putt = 0;
            for(int j = 0; j < max && grid[arr.length - 1 - i][j] == BeadSortStatus.MARKED; j++) {
                putt++;
            }
            sorted[i] = putt;
        }
        return sorted;
    }
}

Python


  # Part of Cosmos by OpenGenus Foundation
def bead_sort(obj):
    if all([type(x) == int and x >= 0 for x in obj]):
        ref = [range(x) for x in obj]  #for reference
    else:
        raise ValueError("All elements must be positive integers")
    inter = []  #for intermediate
    ind = 0  #for index
    prev = sum([1 for x in ref if len(x) > ind])  #prev for previous
    while prev:
        inter.append(range(prev))
        ind += 1
        prev = sum([1 for x in ref if len(x) > ind])
    ind = 0
    prev = sum([1 for x in inter if len(x) > ind])
    out = []
    while prev:
        out.append(prev)
        ind += 1
        prev = sum([1 for x in inter if len(x) > ind])
    out = out[::-1]
    return out
    
<h3 class="d_active tab_drawer_heading" rel="tab5">Swift</h3>

  /* Part of Cosmos by OpenGenus Foundation */
//
//  bead_sort.swift
//  Created by DaiPei on 2017/10/12.
//
import Foundation
func beadSort(_ array: inout [Int]) {
    let n = array.count
    var m = Int.min
    // find the max value
    for i in 0..<n {
        if array[i] > m {
            m = array[i]
        }
    }
    var beads = [Int8](repeatElement(0, count: m * n))
    // put beads
    for i in 0..<n {
        for j in 0..<m {
            if j < array[i] {
                beads[i * m + j] = 1
            }
        }
    }
    for j in 0..<m {
        // count beads
        var sum = 0
        for i in 0..<n {
            sum += Int(beads[i * m + j])
            beads[i * m + j] = 0
        }
        // move down beads
        for i in n - sum..<n {
            beads[i * m + j] = 1
        }
    }
    // put sorted value in array using beads
    for i in 0..<n {
        var j = 0
        while j < m {
            if beads[i * m + j] == 0 {
                break
            }
            j += 1
        }
        array[i] = j
    }
}