Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insertion Sort by swapping

I've just started to DSA, and had a question about insertion sort.

This the version from textbooks / tutorials.

void insertion_sort(int A[], int n) {
    for (int i = 0; i < n; i++) {
        int temp = A[i];    
        int j = i;

        while (temp < A[j - 1] && j > 0) {
            A[j] = A[j - 1];   
            j = j - 1;
        }
        A[j] = temp;       
    }  
}

I was thinking would it make a difference, if we used swapping numbers instead of shifting the numbers and inserting the temp value in the correct hole position.

void insertionSort(int A[], int n) {
    for (int i = 0; i < n; i++) {
        int temp = A[i];
        int j = i;

        while (temp < A[j - 1] && j > 0) {
            swap(A[j], A[j - 1]);
            j--;
        }
    }
}

Swap Code:

void swap(int &a,int &b){
    int temp = a;
    a = b;
    b = temp;
}

Oh, and it would be really awesome if someone could explain the Time Complexities of both.

like image 869
snbk97 Avatar asked Mar 05 '26 10:03

snbk97


1 Answers

Time complexity for both the approaches is O(N^2) in worst case. But number of operations in the second approach is more as compared to the first because second approach performs the same number of swaps as the number of shifts in the first approach but swap require 3 assignments as compared to just one in in shift-based approach. Hence, method proposed by you will be slower as compared to just shifting the elements.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>

void insertion_shift(int* arr, int n){
    int i,j,k;
    for(i=1;i<n;++i){
        int temp=arr[i];
        for(j=i;j>0 && arr[j-1]>temp;--j)
            arr[j]=arr[j-1];
        arr[j]=temp;
    }
}
void swap(int* a, int* b){
  int temp= *a;
  *a= *b;
  *b= temp;
}

void insertion_swap(int* arr, int n){
   int i,j,k;
   for(i=1;i<n;++i){
      int temp=arr[i];
      for(j=i;j>0 && arr[j-1]>temp;--j)
         swap(&arr[j-1],&arr[j]);
   }
 }      

void print_arr(int* arr, int n){
   int i;
   for(i=0;i<n;++i)
      printf("%d ",arr[i]);
   printf("\n");
}

int main(){
   int n;
   scanf("%d",&n);
   int* arr1= (int*)malloc(sizeof(int)*n);
   int* arr2= (int*)malloc(sizeof(int)*n);
   int i;
   for(i=0;i<n;++i){
      scanf("%d",&arr1[i]);
      arr2[i]=arr1[i];
   }

   struct timespec start, end;
   clock_gettime(CLOCK_MONOTONIC_RAW,&start);
   insertion_shift(arr1,n);
   clock_gettime(CLOCK_MONOTONIC_RAW,&end);
   uint64_t time_shift= (end.tv_sec - start.tv_sec)*1000000 +
                        (end.tv_nsec - start.tv_nsec)/1000;
   printf("using shift: %lld microseconds\n",time_shift);

   clock_gettime(CLOCK_MONOTONIC_RAW,&start);
   insertion_swap(arr2,n);
   clock_gettime(CLOCK_MONOTONIC_RAW,&end);

   uint64_t time_swap= (end.tv_sec - start.tv_sec)*1000000 +
                       (end.tv_nsec - start.tv_nsec)/1000;
   printf("using swap: %lld microseconds\n",time_swap);

}

Here is what I got when I called both functions on the same array of size 10000. Compilation and execution for 10000 elements array. If still not convinced, try to generate a random array of size 1000-10000 and run the above code to observe the difference.

like image 96
yabhishek Avatar answered Mar 08 '26 00:03

yabhishek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!