What is Cocktail Sort
Cocktail sort, also known as cocktail shaker sort or bidirectional bubble sort, is a sorting algorithm that works by repeatedly traversing a list of items in both directions, swapping adjacent elements if they are in the wrong order.
To picture it, imagine a bartender making a cocktail. They start by picking up the shaker and shaking it up and down to mix the ingredients. Similarly, the algorithm starts by going through the list from left to right and swapping any adjacent items that are out of order.
Once it reaches the end of the list, it switches directions and goes back through the list from right to left, again swapping adjacent elements that are in the wrong order. This process is repeated until no more swaps are necessary, at which point the list is considered sorted.
Overall, cocktail sort is similar to bubble sort, but it has the added benefit of sorting the list in both directions, which can sometimes result in faster sorting times.
Who invented it?
The inventor of cocktail sort is not clear as it has been independently discovered and developed by multiple people over the years. However, it is known that the algorithm has been around since the early 20th century and has been used in various forms in different applications. The name "cocktail sort" is said to have been coined in the 1940s by computer scientist and mathematician Donald Knuth in his book "The Art of Computer Programming," in reference to the shuffling action of the algorithm.
Pseudocode
function block_sort(list, block_size):
// Divide the list into blocks of size `block_size`
blocks = []
for i = 0 to length of list, increment by `block_size`:
block = list[i:i+block_size]
blocks.append(block)
// Sort each block using a comparison-based sorting algorithm (e.g. quicksort)
for i = 0 to length of blocks:
sort(blocks[i])
// Merge the sorted blocks back together into a single sorted list
result = []
while length of blocks > 0:
min_block = find_minimum_block(blocks)
result.append(min_block.pop(0))
if length of min_block > 0:
blocks.add(min_block)
else:
remove min_block from blocks
return result
function find_minimum_block(blocks):
min_block = blocks[0]
for block in blocks:
if block[0] < min_block[0]:
min_block = block
return min_block
- The algorithm takes an array of elements as input.
- The variable `n` is set to the length of the array, and two more variables `start` and `end` are initialized to the first and last indices of the array, respectively.
- The algorithm then enters a while loop that continues as long as any swaps are made during the traversals of the array.
- Inside the loop, the algorithm first traverses the array from left to right, comparing adjacent elements and swapping them if they are in the wrong order. If any swaps are made, the `is_swapped` flag is set to `true`.
- If no swaps were made during the left-to-right traversal, the loop is exited early, since the array is already sorted.
- Otherwise, the algorithm traverses the array from right to left, again comparing adjacent elements and swapping them if necessary. If any swaps are made, the `is_swapped` flag is set to `true`.
- If no swaps were made during the right-to-left traversal, the loop is exited early, since the array is already sorted.
- The `start` and `end` variables are adjusted to exclude the elements that have already been sorted, and the loop repeats from the top.
- Once the loop is exited, the sorted array is returned as output.
- The variable `n` is set to the length of the array, and two more variables `start` and `end` are initialized to the first and last indices of the array, respectively.
- The algorithm then enters a while loop that continues as long as any swaps are made during the traversals of the array.
- Inside the loop, the algorithm first traverses the array from left to right, comparing adjacent elements and swapping them if they are in the wrong order. If any swaps are made, the `is_swapped` flag is set to `true`.
- If no swaps were made during the left-to-right traversal, the loop is exited early, since the array is already sorted.
- Otherwise, the algorithm traverses the array from right to left, again comparing adjacent elements and swapping them if necessary. If any swaps are made, the `is_swapped` flag is set to `true`.
- If no swaps were made during the right-to-left traversal, the loop is exited early, since the array is already sorted.
- The `start` and `end` variables are adjusted to exclude the elements that have already been sorted, and the loop repeats from the top.
- Once the loop is exited, the sorted array is returned as output.
Sample Code
// C++ code snippet
vector block_sort(vector list, int block_size) {
// Divide the list into blocks of size `block_size`
vector> blocks;
for (int i = 0; i < list.size(); i += block_size) {
vector block(list.begin() + i, list.begin() + i + block_size);
blocks.push_back(block);
}
// Sort each block using a comparison-based sorting algorithm (e.g. quicksort)
for (int i = 0; i < blocks.size(); i++) {
sort(blocks[i].begin(), blocks[i].end());
}
// Merge the sorted blocks back together into a single sorted list
vector result;
while (blocks.size() > 0) {
vector min_block = blocks[0];
int min_index = 0;
for (int i = 1; i < blocks.size(); i++) {
if (blocks[i][0] < min_block[0]) {
min_block = blocks[i];
min_index = i;
}
}
result.push_back(min_block[0]);
min_block.erase(min_block.begin());
if (min_block.size() > 0) {
blocks[min_index] = min_block;
} else {
blocks.erase(blocks.begin() + min_index);
}
}
return result;
}
int main() {
vector list = { 5, 3, 8, 4, 2, 7, 1, 6 };
int block_size = 3;
vector sorted_list = block_sort(list, block_size);
// Print the sorted list
for (int i = 0; i < sorted_list.size(); i++) {
cout << sorted_list[i] << " ";
}
cout << endl;
return 0;
}
# Python code snippet
def block_sort(lst, block_size):
# Divide the list into blocks of size `block_size`
blocks = [lst[i:i+block_size] for i in range(0, len(lst), block_size)]
# Sort each block using a comparison-based sorting algorithm (e.g. quicksort)
for i in range(len(blocks)):
blocks[i].sort()
# Merge the sorted blocks back together into a single sorted list
result = []
while len(blocks) > 0:
min_block = blocks[0]
min_index = 0
for i in range(1, len(blocks)):
if blocks[i][0] < min_block[0]:
min_block = blocks[i]
min_index = i
result.append(min_block.pop(0))
if len(min_block) > 0:
blocks[min_index] = min_block
else:
blocks.pop(min_index)
return result
# Example usage
lst = [5, 3, 8, 4, 2, 7, 1, 6]
block_size = 3
sorted_lst = block_sort(lst, block_size)
print(sorted_lst)
import java.util.*;
public class BlockSort {
public static List blockSort(List list, int blockSize) {
// Divide the list into blocks of size `blockSize`
List> blocks = new ArrayList<>();
for (int i = 0; i < list.size(); i += blockSize) {
List block = list.subList(i, Math.min(i + blockSize, list.size()));
blocks.add(block);
}
// Sort each block using a comparison-based sorting algorithm (e.g. quicksort)
for (int i = 0; i < blocks.size(); i++) {
Collections.sort(blocks.get(i));
}
// Merge the sorted blocks back together into a single sorted list
List result = new ArrayList<>();
while (blocks.size() > 0) {
List minBlock = blocks.get(0);
int minIndex = 0;
for (int i = 1; i < blocks.size(); i++) {
if (blocks.get(i).get(0) < minBlock.get(0)) {
minBlock = blocks.get(i);
minIndex = i;
}
}
result.add(minBlock.get(0));
minBlock.remove(0);
if (minBlock.size() > 0) {
blocks.set(minIndex, minBlock);
} else {
blocks.remove(minIndex);
}
}
return result;
}
public static void main(String[] args) {
List list = Arrays.asList(5, 3, 8, 4, 2, 7, 1, 6);
int blockSize = 3;
List sortedList = blockSort(list, blockSize);
// Print the sorted list
System.out.println(sortedList);
}
}