Comparison among Bubble Sort, Selection Sort and Insertion Sort
Last Updated :
11 Jul, 2025
Bubble Sort, Selection Sort, and Insertion Sort are simple sorting algorithms that are commonly used to sort small datasets or as building blocks for more complex sorting algorithms. Here's a comparison of the three algorithms:
Bubble Sort:
- Time complexity: O(n^2) in the worst and average cases, O(n) in the best case (when the input array is already sorted)
Space complexity: O(1) - Basic idea: Iterate through the array repeatedly, comparing adjacent pairs of elements and swapping them if they are in the wrong order. Repeat until the array is fully sorted.
Selection Sort:
- Time complexity: O(n^2) in all cases (worst, average, and best)
Space complexity: O(1) - Basic idea: Find the minimum element in the unsorted portion of the array and swap it with the first unsorted element. Repeat until the array is fully sorted.
Insertion Sort:
- Time complexity: O(n^2) in the worst and average cases, O(n) in the best case (when the input array is already sorted)
Space complexity: O(1) - Basic idea: Build up a sorted subarray from left to right by inserting each new element into its correct position in the subarray. Repeat until the array is fully sorted.
Comparison:
- Bubble Sort, Selection Sort, and Insertion Sort all have the same worst-case and average-case time complexity of O(n²). However, Insertion Sort generally performs better in practice, especially on nearly sorted data, due to fewer swaps and comparisons, making it more efficient in average scenarios compared to Bubble Sort and Selection Sort.
- Insertion Sort has the best-case time complexity of O(n) when the input array is already sorted, which is not possible for Bubble Sort and Selection Sort.
- Selection Sort and Insertion Sort both have the same space complexity of O(1), while Bubble Sort also has a space complexity of O(1).
- Bubble Sort and Insertion Sort are stable sorting algorithms, meaning that they preserve the relative order of equal elements in the sorted array, while Selection Sort is not stable.
- In terms of performance, Insertion Sort tends to perform better than Bubble Sort and Selection Sort for small datasets, while Bubble Sort and Selection Sort may perform better than Insertion Sort for larger datasets or datasets that are partially sorted.
Overall, each algorithm has its own advantages and disadvantages, and the choice of which algorithm to use depends on the specific requirements of the problem at hand.
Advantages and disadvantages of each algorithm
Bubble Sort:
Advantages: Simple implementation, works well for small datasets, requires only constant space, stable sorting algorithm
Disadvantages: Inefficient for large datasets, worst-case time complexity of O(n^2), not optimal for partially sorted datasets
Selection Sort:
Advantages: Simple implementation, works well for small datasets, requires only constant space, in-place sorting algorithm
Disadvantages: Inefficient for large datasets, worst-case time complexity of O(n^2), not optimal for partially sorted datasets, not a stable sorting algorithm
Insertion Sort:
Advantages: Simple implementation, works well for small datasets, requires only constant space, efficient for partially sorted datasets, stable sorting algorithm
Disadvantages: Inefficient for large datasets, worst-case time complexity of O(n^2)
Code (Python implementation):
C++
#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;
// Function to perform Bubble Sort
void bubble_sort(vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n - i - 1; ++j) {
if (arr[j] > arr[j + 1]) {
// Swapping elements
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// Function to perform Selection Sort
void selection_sort(vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n; ++i) {
int min_index = i;
for (int j = i + 1; j < n; ++j) {
if (arr[j] < arr[min_index]) {
min_index = j;
}
}
// Swapping elements
int temp = arr[i];
arr[i] = arr[min_index];
arr[min_index] = temp;
}
}
// Function to perform Insertion Sort
void insertion_sort(vector<int>& arr) {
int n = arr.size();
for (int i = 1; i < n; ++i) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
int main() {
// Generate a vector of 10000 random integers
vector<int> arr;
srand(time(nullptr)); // Seed for random number generation
for (int i = 0; i < 10000; ++i) {
arr.push_back(rand() % 10000 + 1); // Generate random numbers between 1 and 10000
}
vector<int> temp = arr;
// Sort the vector using each algorithm and measure time
clock_t start_time, end_time;
start_time = clock();
bubble_sort(arr);
end_time = clock();
double bubble_sort_time = double(end_time - start_time) / CLOCKS_PER_SEC;
arr = temp;
start_time = clock();
selection_sort(arr);
end_time = clock();
double selection_sort_time = double(end_time - start_time) / CLOCKS_PER_SEC;
arr = temp;
start_time = clock();
insertion_sort(arr);
end_time = clock();
double insertion_sort_time = double(end_time - start_time) / CLOCKS_PER_SEC;
// Print the time taken by each sorting algorithm
cout << "Bubble Sort time: " << bubble_sort_time << endl;
cout << "Selection Sort time: " << selection_sort_time << endl;
cout << "Insertion Sort time: " << insertion_sort_time << endl;
return 0;
}
Java
import java.util.Random;
public class SortingAlgorithms {
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
public static void selectionSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
public static void insertionSort(int[] arr) {
int n = arr.length;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
public static void main(String[] args) {
int[] arr = new int[1000];
Random rand = new Random();
for (int i = 0; i < 1000; i++) {
arr[i] = rand.nextInt(10000) + 1;
}
int[] temp = arr;
long startTime = System.nanoTime();
bubbleSort(arr.clone());
long bubbleSortTime = System.nanoTime() - startTime;
arr = temp;
startTime = System.nanoTime();
selectionSort(arr.clone());
long selectionSortTime = System.nanoTime() - startTime;
arr = temp;
startTime = System.nanoTime();
insertionSort(arr.clone());
long insertionSortTime = System.nanoTime() - startTime;
System.out.println("Bubble Sort time: " + bubbleSortTime);
System.out.println("Selection Sort time: " + selectionSortTime);
System.out.println("Insertion Sort time: " + insertionSortTime);
}
}
Python
import random
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
def selection_sort(arr):
n = len(arr)
for i in range(n):
min_index = i
for j in range(i + 1, n):
if arr[j] < arr[min_index]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
def insertion_sort(arr):
n = len(arr)
for i in range(1, n):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
# Generate a list of 10000 random integers
arr = [random.randint(1, 10000) for i in range(800)]
# Sort the list using each algorithm and time it
import time
temp = arr;
start_time = time.time()
bubble_sort(arr.copy())
bubble_sort_time = time.time() - start_time
arr = temp;
start_time = time.time()
selection_sort(arr.copy())
selection_sort_time = time.time() - start_time
arr = temp;
start_time = time.time()
insertion_sort(arr.copy())
insertion_sort_time = time.time() - start_time
print("Bubble Sort time:", bubble_sort_time)
print("Selection Sort time:", selection_sort_time)
print("Insertion Sort time:", insertion_sort_time)
C#
using System;
using System.Diagnostics;
using System.Linq;
public class SortingAlgorithms {
public static void BubbleSort(int[] arr) {
int n = arr.Length;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
public static void SelectionSort(int[] arr) {
int n = arr.Length;
for (int i = 0; i < n; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
public static void InsertionSort(int[] arr) {
int n = arr.Length;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
public static void Main(string[] args) {
int[] arr = new int[10000];
Random rand = new Random();
for (int i = 0; i < 10000; i++) {
arr[i] = rand.Next(10000) + 1;
}
int[] temp = arr;
Stopwatch sw = new Stopwatch();
sw.Start();
BubbleSort((int[])arr.Clone());
sw.Stop();
long bubbleSortTime = sw.ElapsedTicks;
arr = temp;
sw.Restart();
SelectionSort((int[])arr.Clone());
sw.Stop();
long selectionSortTime = sw.ElapsedTicks;
arr = temp;
sw.Restart();
InsertionSort((int[])arr.Clone());
sw.Stop();
long insertionSortTime = sw.ElapsedTicks;
Console.WriteLine("Bubble Sort time: " + bubbleSortTime);
Console.WriteLine("Selection Sort time: " + selectionSortTime);
Console.WriteLine("Insertion Sort time: " + insertionSortTime);
}
}
JavaScript
// Function to generate a random integer between min (inclusive) and max (inclusive)
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Function to perform Bubble Sort
function bubbleSort(arr) {
const n = arr.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Swap arr[j] and arr[j + 1]
const temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// Function to perform Selection Sort
function selectionSort(arr) {
const n = arr.length;
for (let i = 0; i < n; i++) {
let minIndex = i;
for (let j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Swap arr[i] and arr[minIndex]
const temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
// Function to perform Insertion Sort
function insertionSort(arr) {
const n = arr.length;
for (let i = 1; i < n; i++) {
const key = arr[i];
let j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
// Main function
function main() {
let arr = new Array(10000);
// Populate the array with random values
for (let i = 0; i < 10000; i++) {
arr[i] = getRandomInt(1, 10000); // Adjust the range as needed
}
let temp = arr;
const startTimeBubble = performance.now();
bubbleSort(arr);
const bubbleSortTime = performance.now() - startTimeBubble;
arr = temp;
const startTimeSelection = performance.now();
selectionSort([...arr]);
const selectionSortTime = performance.now() - startTimeSelection;
arr = temp;
const startTimeInsertion = performance.now();
insertionSort([...arr]);
const insertionSortTime = performance.now() - startTimeInsertion;
console.log("Bubble Sort time: " + bubbleSortTime.toFixed(2) + " ms");
console.log("Selection Sort time: " + selectionSortTime.toFixed(2) + " ms");
console.log("Insertion Sort time: " + insertionSortTime.toFixed(2) + " ms");
}
// Call the main function
main();
OutputBubble Sort time: 0.133182
Selection Sort time: 0.03515
Insertion Sort time: 0.017741
In this example, we use the same code to sort a list of 10000 random integers using Bubble Sort, Selection Sort, and Insertion Sort. We then time each algorithm's execution using the time module.
As shown in the output, Insertion Sort is much faster than Bubble Sort and Selection Sort for this dataset. However, it's important to note that the performance of each algorithm can vary depending on the specific characteristics of the dataset.
Bubble sort repeatedly compares and swaps(if needed) adjacent elements in every pass. In i-th pass of Bubble Sort (ascending order), last (i-1) elements are already sorted, and i-th largest element is placed at (N-i)-th position, i.e. i-th last position.
Algorithm:
BubbleSort (Arr, N) // Arr is an array of size N.
{
For ( I:= 1 to (N-1) ) // N elements => (N-1) pass
{
// Swap adjacent elements of Arr[1:(N-I)]such that
// largest among { Arr[1], Arr[2], ..., Arr[N-I] } reaches to Arr[N-I]
For ( J:= 1 to (N-I) ) // Execute the pass
{
If ( Arr [J] > Arr[J+1] )
Swap( Arr[j], Arr[J+1] );
}
}
}
Optimization of Algorithm: Check if there happened any swapping operation in the inner loop (pass execution loop) or not. If there is no swapping in any pass, it means the array is now fully sorted, hence no need to continue, stop the sorting operation. So we can optimize the number of passes when the array gets sorted before the completion of all passes. And it can also detect if the given / input array is sorted or not, in the first pass.
BubbleSort (Arr, N) // Arr is an array of size N.
{
For ( I:= 1 to (N-1) ) // N elements => (N-1) pass
{
// Swap adjacent elements of Arr[1:(N-I)]such that
// largest among { Arr[1], Arr[2], ..., Arr[N-I] } reaches to Arr[N-I]
noSwap = true; // Check occurrence of swapping in inner loop
For ( J:= 1 to (N-I) ) // Execute the pass
{
If ( Arr [J] > Arr[J+1] )
{
Swap( Arr[j], Arr[J+1] );
noSwap = false;
}
}
If (noSwap) // exit the loop
break;
}
}
Time Complexity:
- Best Case Sorted array as input. Or almost all elements are in proper place. [ O(N) ]. O(1) swaps.
- Worst Case: Reversely sorted / Very few elements are in proper place. [ O(N2) ] . O(N2) swaps.
- Average Case: [ O(N2) ] . O(N2) swaps.
Space Complexity: A temporary variable is used in swapping [ auxiliary, O(1) ]. Hence it is In-Place sort.
Advantage:
- It is the simplest sorting approach.
- Best case complexity is of O(N) [for optimized approach] while the array is sorted.
- Using optimized approach, it can detect already sorted array in first pass with time complexity of O(N).
- Stable sort: does not change the relative order of elements with equal keys.
- In-Place sort.
Disadvantage:
- Bubble sort is comparatively slower algorithm.
- Poor efficiency for large elements of array.
Selection sort selects i-th smallest element and places at i-th position. This algorithm divides the array into two parts: sorted (left) and unsorted (right) subarray. It selects the smallest element from unsorted subarray and places in the first position of that subarray (ascending order). It repeatedly selects the next smallest element.
Algorithm:
SelectionSort (Arr, N) // Arr is an array of size N.
{
For ( I:= 1 to (N-1) ) // N elements => (N-1) pass
{
// I=N is ignored, Arr[N] is already at proper place.
// Arr[1:(I-1)] is sorted subarray, Arr[I:N] is unsorted subarray
// smallest among { Arr[I], Arr[I+1], Arr[I+2], ..., Arr[N] } is at place min_index
min_index = I;
For ( J:= I+1 to N ) // Search Unsorted Subarray (Right lalf)
{
If ( Arr [J] < Arr[min_index] )
min_index = J; // Current minimum
}
// Swap I-th smallest element with current I-th place element
If (min_Index != I)
Swap ( Arr[I], Arr[min_index] );
}
}
Time Complexity:
- Best Case [ O(N2) ]. And O(1) swaps.
- Worst Case: Reversely sorted, and when the inner loop makes a maximum comparison. [ O(N2) ] . Also, O(N) swaps.
- Average Case: [ O(N2) ] . Also O(N) swaps.
Space Complexity: [ auxiliary, O(1) ]. In-Place sort.(When elements are shifted instead of being swapped (i.e. temp=a[min], then shifting elements from ar[i] to ar[min-1] one place up and then putting a[i]=temp). If swapping is opted for, the algorithm is not In-place.)
Advantage:
- It can also be used on list structures that make add and remove efficient, such as a linked list. Just remove the smallest element of unsorted part and end at the end of sorted part.
- The number of swaps reduced. O(N) swaps in all cases.
- In-Place sort.
Disadvantage:
- Time complexity in all cases is O(N2), no best case scenario.
- It requires n-squared number of steps for sorting n elements.
- It is not scalable.
Insertion Sort is a simple comparison based sorting algorithm. It inserts every array element into its proper position. In i-th iteration, previous (i-1) elements (i.e. subarray Arr[1:(i-1)]) are already sorted, and the i-th element (Arr[i]) is inserted into its proper place in the previously sorted subarray.
Find more details in this GFG Link.
Algorithm:
InsertionSort (Arr, N) // Arr is an array of size N.
{
For ( I:= 2 to N ) // N elements => (N-1) pass
{
// Pass 1 is trivially sorted, hence not considered
// Subarray { Arr[1], Arr[2], ..., Arr[I-I] } is already sorted
insert_at = I; // Find suitable position insert_at, for Arr[I]
// Move subarray Arr [ insert_at: I-1 ] to one position right
item = Arr[I]; J=I-1;
While ( J ? 1 && item < Arr[J] )
{
Arr[J+1] = Arr[J]; // Move to right
// insert_at = J;
J--;
}
insert_at = J+1; // Insert at proper position
Arr[insert_at] = item; // Arr[J+1] = item;
}
}
}
Time Complexity:
- Best Case Sorted array as input, [ O(N) ]. And O(1) swaps.
- Worst Case: Reversely sorted, and when inner loop makes maximum comparison, [ O(N2) ] . And O(N2) swaps.
- Average Case: [ O(N2) ] . And O(N2) swaps.
Space Complexity: [ auxiliary, O(1) ]. In-Place sort.
Advantage:
- It can be easily computed.
- Best case complexity is of O(N) while the array is already sorted.
- Number of swaps reduced than bubble sort.
- For smaller values of N, insertion sort performs efficiently like other quadratic sorting algorithms.
- Stable sort.
- Adaptive: total number of steps is reduced for partially sorted array.
- In-Place sort.
Disadvantage:
- It is generally used when the value of N is small. For larger values of N, it is inefficient.
- Similar as selection sort it requires n-squared number of steps for sorting n elements.
Time and Space Complexity:
Sorting Algorithm | Time Complexity | Space Complexity |
---|
| Best Case | Average Case | Worst Case | Worst Case |
Bubble Sort | O(N) | O(N2) | O(N2) | O(1) |
Selection Sort | O(N2) | O(N2) | O(N2) | O(1) |
Insertion Sort | O(N) | O(N2) | O(N2) | O(1) |
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem