Block sort is a sorting algorithm that sorts an array by dividing it into blocks of fixed size, sorting each block individually, and then merging the sorted blocks back into a single sorted array. Block sort is a good choice for sorting large datasets that do not fit in memory. It can efficiently sort data in blocks that fit in memory, and then merge the sorted blocks together to obtain the final sorted array.
Approach: The block sort approach is as follows:
- Divide the input array into blocks of fixed size.
- Sort each block using a comparison-based sorting algorithm (e.x., quicksort or mergesort).
- Merge the sorted blocks back into a single sorted array using a priority queue or min-heap.
Illustration:
Let the given array be: [1, 7, 8, 2, 3, 5, 4, 6]
- Let’s choose a block size of 3. So we will divide the input into blocks of 3 integers each:
- Block 1: [1, 7, 8]
- Block 2: [2, 3, 5]
- Block 3: [4, 6]
- Now we sort each block individually using a comparison-based sorting algorithm. Let’s use quicksort for this example. Here are the sorted blocks:
- Block 1: [1, 7, 8]
- Block 2: [2, 3, 5]
- Block 3: [4, 6]
- Now we merge the sorted blocks together. We create a min-heap that contains the first element from each block:
min-heap: [1, 2, 4]
- We extract the minimum element (1) from the heap and add it to the output array, replacing it with the next element from the block it came from:
- Output: [1]
- min-heap: [2, 7, 4]
- We extract the minimum element (2) from the heap and add it to the output array, replacing it with the next element from the block it came from:
- Output: [1, 2]
- min-heap: [4, 7, 5]
- We extract the minimum element (4) from the heap and add it to the output array, replacing it with the next element from the block it came from:
- Output: [1, 2, 4]
- min-heap: [5, 7, 8]
- We extract the minimum element (5) from the heap and add it to the output array, replacing it with the next element from the block it came from:
Output: [1, 2, 4, 5]
min-heap: [6, 7, 8]
- We extract the minimum element (6) from the heap and add it to the output array, replacing it with the next element from the block it came from:
- Output: [1, 2, 4, 5, 6]
- min-heap: [7, 8]
- We extract the minimum element (7) from the heap and add it to the output array, replacing it with the next element from the block it came from:
- Output: [1, 2, 4, 5, 6, 7]
- min-heap: [8]
- We extract the minimum element (8) from the heap and add it to the output array, replacing it with the next element from the block it came from.
- Output: [1, 2, 4, 5, 6, 7, 8]
Below is the implementation of the above approach:
#include <algorithm> #include <iostream> #include <vector> using namespace std;
vector< int > blockSort(vector< int > arr, int blockSize)
{ vector<vector< int > > blocks;
// Divide the input array into blocks of size blockSize
for ( int i = 0; i < arr.size(); i += blockSize) {
vector< int > block;
for ( int j = i; j < i + blockSize && j < arr.size();
j++) {
block.push_back(arr[j]);
}
// Sort each block and append it to the list of
// sorted blocks
sort(block.begin(), block.end());
blocks.push_back(block);
}
// Merge the sorted blocks into a single sorted list
vector< int > result;
while (!blocks.empty()) {
// Find the smallest element in the first block of
// each sorted block
int minIdx = 0;
for ( int i = 1; i < blocks.size(); i++) {
if (blocks[i][0] < blocks[minIdx][0]) {
minIdx = i;
}
}
// Remove the smallest element and append it to the
// result list
result.push_back(blocks[minIdx][0]);
blocks[minIdx].erase(blocks[minIdx].begin());
// If the block is now empty, remove it from the
// list of sorted blocks
if (blocks[minIdx].empty()) {
blocks.erase(blocks.begin() + minIdx);
}
}
return result;
} int main()
{ // Original arr
vector< int > arr = { 1, 7, 8, 2, 3, 5, 4, 6 };
cout << "Input: " ;
for ( int i = 0; i < arr.size(); i++) {
cout << arr[i] << " " ;
}
cout << endl;
// Select box size
int blockSize = 3;
// Function call
vector< int > sortedArr = blockSort(arr, blockSize);
// Output the sorted array
cout << "Output: " ;
for ( int i = 0; i < sortedArr.size(); i++) {
cout << sortedArr[i] << " " ;
}
cout << endl;
return 0;
} |
// Java Implementation import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class GFG {
public static List<Integer> blockSort(List<Integer> arr,
int blockSize)
{
List<List<Integer> > blocks = new ArrayList<>();
// Divide the input array into blocks of size
// blockSize
for ( int i = 0 ; i < arr.size(); i += blockSize) {
List<Integer> block = new ArrayList<>();
for ( int j = i;
j < i + blockSize && j < arr.size(); j++) {
block.add(arr.get(j));
}
// Sort each block and append it to the list of
// sorted blocks
Collections.sort(block);
blocks.add(block);
}
// Merge the sorted blocks into a single sorted list
List<Integer> result = new ArrayList<>();
while (!blocks.isEmpty()) {
// Find the smallest element in the first block
// of each sorted block
int minIdx = 0 ;
for ( int i = 1 ; i < blocks.size(); i++) {
if (blocks.get(i).get( 0 )
< blocks.get(minIdx).get( 0 )) {
minIdx = i;
}
}
// Remove the smallest element and append it to
// the result list
result.add(blocks.get(minIdx).remove( 0 ));
// If the block is now empty, remove it from the
// list of sorted blocks
if (blocks.get(minIdx).isEmpty()) {
blocks.remove(minIdx);
}
}
return result;
}
// Driver code
public static void main(String[] args)
{
// Original arr
List<Integer> arr = new ArrayList<>();
arr.add( 1 );
arr.add( 7 );
arr.add( 8 );
arr.add( 2 );
arr.add( 3 );
arr.add( 5 );
arr.add( 4 );
arr.add( 6 );
System.out.println( "Input: " + arr);
// Select box size
int blockSize = 3 ;
// Function call
System.out.println( "Output: "
+ blockSort(arr, blockSize));
}
} |
# Python Implementation def block_sort(arr, block_size):
# Create an empty list to
# hold the sorted blocks
blocks = []
# Divide the input array into
# blocks of size block_size for i in range ( 0 , len (arr), block_size):
block = arr[i:i + block_size]
# Sort each block and append
# it to the list of sorted blocks
blocks.append( sorted (block))
# Merge the sorted blocks into
# a single sorted list
result = []
while blocks:
# Find the smallest element in
# the first block of
# each sorted block
min_idx = 0
for i in range ( 1 , len (blocks)):
if blocks[i][ 0 ] < blocks[min_idx][ 0 ]:
min_idx = i
# Remove the smallest element and
# append it to the result list
result.append(blocks[min_idx].pop( 0 ))
# If the block is now empty, remove
# it from the list of sorted blocks
if len (blocks[min_idx]) = = 0 :
blocks.pop(min_idx)
return result
# Original arr arr = [ 1 , 7 , 8 , 2 , 3 , 5 , 4 , 6 ]
print ( 'Input: ' , arr)
# Select box size block_size = 3
# Function call print ( 'Output:' , block_sort(arr, block_size))
|
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG
{ static List< int > BlockSort(List< int > arr, int blockSize)
{
List<List< int >> blocks = new List<List< int >>();
// Divide the input array into blocks of size blockSize
for ( int i = 0; i < arr.Count; i += blockSize)
{
List< int > block = new List< int >();
for ( int j = i; j < i + blockSize && j < arr.Count; j++)
{
block.Add(arr[j]);
}
// Sort each block and append it to the list of sorted blocks
block.Sort();
blocks.Add(block);
}
// Merge the sorted blocks into a single sorted list
List< int > result = new List< int >();
while (blocks.Any())
{
// Find the smallest element in the first block of each sorted block
int minIdx = 0;
for ( int i = 1; i < blocks.Count; i++)
{
if (blocks[i][0] < blocks[minIdx][0])
{
minIdx = i;
}
}
// Remove the smallest element and append it to the result list
result.Add(blocks[minIdx][0]);
blocks[minIdx].RemoveAt(0);
// If the block is now empty, remove it from the list of sorted blocks
if (!blocks[minIdx].Any())
{
blocks.RemoveAt(minIdx);
}
}
return result;
}
static public void Main()
{
// Original arr
List< int > arr = new List< int > { 1, 7, 8, 2, 3, 5, 4, 6 };
Console.Write( "Input: " );
for ( int i = 0; i < arr.Count; i++)
{
Console.Write(arr[i] + " " );
}
Console.WriteLine();
// Select box size
int blockSize = 3;
// Function call
List< int > sortedArr = BlockSort(arr, blockSize);
// Output the sorted array
Console.Write( "Output: " );
for ( int i = 0; i < sortedArr.Count; i++)
{
Console.Write(sortedArr[i] + " " );
}
Console.WriteLine();
}
} // This code is contributed by Siddharth Aher |
function blockSort(arr, blockSize) {
let blocks = [];
// Divide the input array into blocks of size blockSize
for (let i = 0; i < arr.length; i += blockSize) {
let block = [];
for (let j = i; j < i + blockSize && j < arr.length; j++) {
block.push(arr[j]);
}
// Sort each block and append it to the list of sorted blocks
block.sort((a, b) => a - b);
blocks.push(block);
}
// Merge the sorted blocks into a single sorted list
let result = [];
while (blocks.length > 0) {
// Find the smallest element in the first block of each sorted block
let minIdx = 0;
for (let i = 1; i < blocks.length; i++) {
if (blocks[i][0] < blocks[minIdx][0]) {
minIdx = i;
}
}
// Remove the smallest element and append it to the result list
result.push(blocks[minIdx][0]);
blocks[minIdx].shift();
// If the block is now empty, remove it from the list of sorted blocks
if (blocks[minIdx].length === 0) {
blocks.splice(minIdx, 1);
}
}
return result;
} // Original arr let arr = [1, 7, 8, 2, 3, 5, 4, 6]; console.log( "Input: " + arr.join( " " ));
// Select box size let blockSize = 3; // Function call let sortedArr = blockSort(arr, blockSize); // Output the sorted array console.log( "Output: " + sortedArr.join( " " ));
|
Input: [1, 7, 8, 2, 3, 5, 4, 6] Output: [1, 2, 3, 4, 5, 6, 7, 8]
Time Complexity: O(n*logn)
Auxiliary Space: O(1).
Advantages of Block Sort:
- Block sort has a relatively good worst-case time complexity of O(n*logn).
- Block sort can be efficiently parallelized by sorting each block separately in parallel.
- Block sort can handle large datasets that do not fit in memory by sorting the data in blocks that fit in memory.
Disadvantages of Block Sort:
- Block sort has a relatively high overhead due to the need to divide the input into blocks and then merge the sorted blocks together.
- The choice of block size can affect the performance of block sort. If the block size is too small, there will be more blocks to sort, which increases the overhead. If the block size is too large, the individual blocks may not fit in memory, reducing the efficiency of block sort.
Why Block Sort is better than Other Sorting Algorithms?
- Block sort is often used when sorting very large arrays that cannot fit into memory at once, as it allows the array to be sorted into smaller, more manageable pieces. In contrast, many other sorting algorithms require that the entire array be loaded into memory before sorting can begin.
- The performance characteristics of block sort can vary depending on the specific algorithm used and the size of the blocks. In general, block sorting can be very efficient for sorting large data sets. Other sorting algorithms may have different performance characteristics depending on factors such as the data distribution
- Block sort algorithms can be efficient for sorting large data sets, but they can also be complex to implement and may require specialized hardware or software