Showing posts with label Sorting Technique. Show all posts
Showing posts with label Sorting Technique. Show all posts

Thursday, 3 May 2012

File Sorting - 2 Source 2 Destination


The problem with 2S - 1D is the explicit run distribution that occurs after each merge. It doubles the pressure on the disk queue. We can reduce this pressure drastically by allocating one more frame and designing the file sorting algorithm for 2 sources and 2 destinations (2S - 2D).

There will be four files F1, F2, F3 and F4. We have marked and distributed runs in F1 and F2. 

First take F1 & F2 as sources S1, S2 and F3 & F4 as destinations D1, D2 respectively. Take a run from S1 and a run from S2. Merge and place in D1 then switch the destination to D2. Take another run from S1 and S2, merge and place in D2. Again switch the destination. If end of file is encountered in S1 and S2 then D1 and D2 will become new sources and S1 and S2 will become new destination files. Hence the data movement will be from source to destination. Which pair of files will be source and which pair will be destination, will keep on changing as per time. 

At the end there will be one run on S1 and one run on S2. Merge and write on D1. As no data to write on D2, hence all the data is sorted.

The algorithm for the sub procedure for merging 2S-2D is as follows.
MergeRuns(boolean flag)
1. runCount=0;
2. if(flag==true)
 s1 = Reset(F1)
 s2 = Reset(F2)
 d1 = Rewrite(F3)
 d2 = Rewrite(F4)
   Else
 s1 = Reset(F3)
 s2 = Reset(F4)
 d1 = Rewrite(F1)
 d2 = Rewrite(F2)
   End if
3. e1 = Read(s1)
4. e2 = Read(s2)
5. d = d1;
6. While ( e1 != eof  and e2 !=eof)
 While (e1 != eor and e2 !=eor)
  If(e1<e2)
   Write(d, e1)
   e1 = Read(s1)
  Else
   Write(d, e2)
   e2 = Read(s2)
  End if
 End While

 If (e1 == eor)
  Copy remaining elements of the run from s2
 Else if (e2 == eor)
  Copy remaining elements of the run from s1
 End if
 Mark eor in d
 runCount++;
 
 If (d==d1)
  d=d2
 Else
  d=d1
 End if
   End While
7. If(e1==eof)
 While (e2 != eof)
  Write(e2,d)
  If(e2==eor) runCount++;
  Read(e2,s2)
 End While
   Else if(e2==eof)
 While (e1 != eof)
  Write(e1,d)
  If(e1==eor) runCount++;
  Read(e1,s1)
 End While
   End if
8. Mark EOF in d1
9. Mark EOF in d2
10.Return runCount


A program in C to sort file using 2S - 2D technique.

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

#define eor -1
#define eof -2

FILE *f1, *f2, *d1, *d2;

markRunsAndDistribute();
mergeRuns(int);


void main()
{
 int flag=0;
 markRunsAndDistribute();

 while(mergeRuns(flag)!=1)
  flag=1-flag;

 printf("File Sorted....");
}

markRunsAndDistribute()
{
 int runCount=0;
 int current, next;
 int switchFlag=1;


 if( (d1 = fopen("Source.txt", "r")) == NULL)
 {
  printf("Source file not found.");
  exit(1);
 }

 f1 = fopen("File1.txt","w");
 f2 = fopen("File2.txt", "w");

 fscanf(d1,"%d",¤t);

 while(1)
 {
  fscanf(d1, "%d", &next);

  if(next==eof)
  {
   if(switchFlag==1)
   {       fprintf(f1, "%d %d %d",current,eor,eof);
    fprintf(f2, "%d",eof);
    runCount++;
    break;
   }
   else
   {
    fprintf(f2, "%d %d %d",current,eor,eof);
    fprintf(f1, "%d",eof);
    runCount++;
    break;
   }
  }
  else
  {
   if(current>next)
   {
    if(switchFlag==1)
    {
     fprintf(f1, "%d %d ", current, eor);
     runCount++;
     switchFlag=2;
    }
    else
    {
     fprintf(f2, "%d %d ", current, eor);
     runCount++;
     switchFlag=1;
    }
   }
   else
   {
    if(switchFlag==1)
    {
        fprintf(f1, "%d ", current);
    }
    else
    {
        fprintf(f2, "%d ", current);
    }

   }
  }
  current = next;
 }

 fclose(d1);
 fclose(f1);
 fclose(f2);

 return runCount;
}

mergeRuns(int group)
{
 int switchD=0;
 int runCount=0;
 FILE *d;

 int e1, e2;

 if(group==0)
 {
  f1 = fopen("File1.txt","r");
  f2 = fopen("File2.txt","r");
  d1 = fopen("File3.txt","w");
  d2 = fopen("File4.txt","w");
 }
 else
 {
  f1 = fopen("File3.txt","r");
  f2 = fopen("File4.txt","r");
  d1 = fopen("File1.txt","w");
  d2 = fopen("File2.txt","w");
 }

 
 fscanf(f1,"%d",&e1);
 fscanf(f2,"%d",&e2);

 d=d1;

 while (e1!=eof && e2!=eof)
 {
  while(e1!=eor && e2!=eor)
  {
   if(e1<e2)
   {
    fprintf(d,"%d ",e1);
    fscanf(f1,"%d",&e1);
   }
   else
   {
    fprintf(d,"%d ",e2);
    fscanf(f2,"%d",&e2);
   }
  }

  if(e1==eor)
  {
   while (e2!=eor)
   {
    fprintf(d, "%d ", e2);
    fscanf(f2, "%d", &e2);
   }
  }
  else if(e2==eor)
  {
   while (e1!=eor)
   {
    fprintf(d, "%d ", e1);
    fscanf(f1, "%d", &e1);
   }
  }

  fprintf(d, "%d ", eor);
  runCount++;

  if(d==d1)
   d=d2;
  else
   d=d1;

  fscanf(f1,"%d",&e1);
  fscanf(f2,"%d",&e2);
  
 }
 if(e1==eof)
 {
  while (e2!=eof)
  {
   fprintf(d, "%d ", e2);
   if(e2==eor) runCount++;
   fscanf(f2, "%d", &e2);
  }
 }
 else if(e2==eof)
 {
  while (e1!=eof)
  {
   fprintf(d, "%d ", e1);
   if(e1==eor) runCount++;
   fscanf(f1, "%d", &e1);
  }
 }

 fprintf(d1,"%d",eof);
 fprintf(d2,"%d",eof);
 

 fclose(f1);
 fclose(f2);
 fclose(d1);
 fclose(d2);

 return runCount;
}

Advantage of 2S - 2D

Consider a file with 1K record. To fetch (read and write) a record 1 disk access is required and to distribute the record in two files 1K disk access.



Approximately half the number of disk accesses are saved in 2S – 2D. Hence by giving one extra frame the pressure on the disk queue is reduced drastically.

File Sorting - 2 Source 1 Destination

Introduction
A file is a series of records. A record consists of one or more fields. One of the fields in the record is called as key field which is used to uniquely identify a record. E.g. A student’s record consists of Roll Number, Name, Class, Subjects, and Marks etc. fields; of this Roll Number is the key field as it is used to uniquely identify a student. One student is one instance with one record each. These instances are called series of records. Record in a file is synonym to tuple is the database. A record consists of field(s). Tuple is described with column(s).

While working with files, if the records are of fixed length with fixed number of fields in a fixed order then a structure can be defined to store the record. If records are of variable length then we use explicit delimiters to separate two records. The delimiter should be distinct and should not be used in the record. It is always predefined.

File Sorting
A file consists of millions of records. The size of a file is usually in GBs. To sort some data, all the data to be sorted must be visible (loaded in the RAM) at the time of sorting. As RAMs are in MBs hence the entire file cannot be loaded on the RAM. On a RAM only a small portion of the file is loaded in a frame. Each frame will hold a page of the file. The size of the page is defined by the register lines of the CPU.

Consider of the millions of records from a file, you are able to load only three records at a time in a frame. Hence at some point of time you can see only those records that can fit on a page depending on size of records fetched in RAM.

This is something which we need to adjust because in array sorting, you can see all elements but in files only a fraction is visible. Hence file sorting is different than arrays.

Why to sort a file?
  1. In database, we want to remove duplicate records.
  2. We are required to process some data in order. E.g. In a bank, highest depositors should be processed first.
  3. If there is a sort merge join.
While sorting, the things which are compared should be compatible. E.g. Comparison can be between roll numbers, date of births etc.

We will sort record on particular field where ordering exists and the rest (baggage) will not be considered. A record will be considered as consisting of Key & Baggage. If key is shifted then entire record including baggage will be shifted.

For us at this learning stage, a file consists of only keys which are to be sorted. To order keys, we need minimum 2 keys visible at a time. As only a page is loaded on a frame, we have a narrow window and can see only a couple of records; hence most of the file will be unsorted.

Two source files are must for any file sorting technique. Each file we talk about will be represented by a frame in the memory. We cannot open entire file in multiple frames as we have to work under the restriction of the operating system which are multitasking and many other processes also need RAM.

Minimum four frames are required for sorting (2 Source File + 1 Destination File + 1 Code File). If less than four frames then sorting is not possible.

The general steps for sorting a file are –
1. Start
2. Mark the runs in source file
3. Till number of runs != 1
       Distribute the runs in two or more files
       Merge the runs into a destination file
4. Stop
First we will open up discussion on how to mark runs.

Marking Runs


Note
reset(F0) -> Go to the beginning of the file and start reading.
rewrite(F0) -> Go to the beginning of the file and start writing.

1. Primitive Method

Consider a source file S with key values
76, 53, 5, 15, 20, 29, 31, 37, 41, 40, 50, 49, 91, 61, 81, 76, 1, 2, 3, 4, 5, 6
Now we will go through this file and mark runs. A run is a sorted subsequence of record.

1. Read 2 records
2. Sort those 2 records
3. Place them in F0
4. Mark eor (end of run)
5. Fetch Next two record and go to step 2
6. If no more records then stop

Now the file F0 will be
53, 76 | 5, 15 | 20, 29 | 31, 37| 40, 41| 49, 50| 61, 91| 76, 81| 1, 2| 3, 4| 5, 6|EOF 

But we have not taken advantage of the sortedness of the file hence this primitive method of marking run is not useful.

2. Marking Natural Runs

1. Reset(S)
2. Rewrite(F0)
3. Read record from S s.current
4. Place in F0
5. Read next record from S as s.next
6. If no record then go to step 8
7. If s.current<s.next Then
        Place s.next in F0
        Go to step 3
   Else
        Mark eor in F0
        Place s.next in F0
        Go to step 3
   End if
8. Mark eor in F0
9. Mark eof in F0
10.Stop

Now the file F0 will be
76 | 53 | 5, 15, 20, 29, 31, 37, 41 | 40, 50 | 49, 91 | 61, 81 | 76 | 1, 2, 3, 4, 5, 6 | EOF

<A procedure in C for marking natural runs>
markRuns()
{
 int runCount=0;
 int current, next;

 if( (d = fopen("Source.txt", "r")) == NULL)
 {
  printf("Source file not found.");
  exit(1);
 }

 f1 = fopen("File0.txt","w");

 fscanf(d,"%d",¤t);

 while(1)
 {
  fscanf(d, "%d", &next);

  if(next==eof)
  {
     fprintf(f1, "%d %d %d",current,eor,eof);
     runCount++;
     break;
  }
  else
  {
   if(current>next)
   {
    fprintf(f1, "%d %d ", current, eor);
    runCount++;
   }
   else
   {
    fprintf(f1, "%d ", current);
   }
  }

  current = next;
 }

 fclose(d);
 fclose(f1);
 fclose(f2);

 return runCount;
}


As the data is naturally sorted, hence these are called “Natural Runs”. The runs will be long, fewer and variable in length. This will have fewer passes. A pass is a run through entire data from 1st till last record.

Distributing Runs in two files F1 and F2
This is a very simple method. A flag is uses to switch between files F1 and F2.

1. Set flag=true
2. Reset(F0)
3. Rewrite(F1)
4. Rewrite(F2)
5. Read an element from F0
6. If element is EOF go to step 8
7. If flag is true
        Place the element in F1
        If the element is eor
           flag=false
   Else
        Place the element in F2
        If the element is eor
           flag=true
   End if
8. Mark EOF in F1 and F2
9. Stop

<A procedure in C for distributing runs>
void distributeRuns()
{
 int switchFlag=1;
 int e;

 f1 = fopen("File1.txt", "w");
 f2 = fopen("File2.txt", "w");
 d = fopen("File0.txt", "r");

 fscanf(d,"%d",&e);

 while (e!=eof)
 {
  if(switchFlag==1)
  {
   fprintf(f1, "%d ", e);
   if(e==eor) switchFlag=2;
  }
  else
  {
   fprintf(f2, "%d ", e);
   if(e==eor) switchFlag=1;
  }

  fscanf(d,"%d",&e);
 }

 fprintf(f1, "%d",eof);
 fprintf(f2, "%d",eof);

 fclose(d);
 fclose(f1);
 fclose(f2);
}


Now the contents of the files F1 and F2 will be as follows.

F1: 76 | 5, 15, 20, 29, 31, 37, 41 | 49, 91 | 76 | EOF
F2: 53 | 40, 50 | 61, 81 | 1, 2, 3, 4, 5, 6 | EOF

Mark and Distribute as one procedure
We have passed through the source file twice, 1st time to mark runs and 2nd time to distribute runs. These were explicit mark & distribute operations using two separate sub routines. This can be combined into one subroutine Mark & Distribute. The subroutine for primitive run marking and distribution is as follows. Flag is used to switch between files F1 and F2.
1. Reset(Source)
2. Rewrite(F1)
3. Rewrite(F2)
4. do
    Read frame full of data
    Sort internally using any array sorting algorithm
    If Flag=true
      Copy in F1
      Flag = flase
    Else
      Copy in F2
      Flag = true
    End if
    Mark eor
   Till you reach end of source
5. Stop

Algorithm of subroutine for marking and distributing natural runs is as follows. When we mark end of run, we switch the file and place element. This means that two things will be done at the same time. 1. Marking of runs and 2. Distribution of runs.

1. Reset(Source)
2. Rewrite(F1)
3. Rewrite(F2)
4. Flag=true
5. s.current = Read(source)
6. While (true)
     If(flag==true)
       f=F1;
     Else
       f=F2
     End if
     
     s.next = Read(source)

     If s.next==eof

       Write(s.current,f)
       Mark eor in f
       break

     Else

       If(s.current>s.next)
         Write(s.current, f)
         Mark(eor, f)
         flag=!(flag)
       Else
         Write(s.current, f)
       End if

     End if

     s.current=s.next
   End While
7. Write(F1, eof)
8. Write(F2, eof)
9. Stop

<A sub procedure in C for marking and distributing natural runs>

markRunsAndDistribute()
{
 int runCount=0;
 int current, next;
 int switchFlag=1;

 if( (d = fopen("File0.txt", "r")) == NULL)
 {
  printf("Source file not found.");
  exit(1);
 }

 f1 = fopen("File1.txt","w");
 f2 = fopen("File2.txt", "w");


 fscanf(d,"%d",¤t);

 while(1)
 {
  fscanf(d, "%d", &next);

  if(next==eof)
  {
   if(switchFlag==1)
   {       fprintf(f1, "%d %d %d",current,eor,eof);
    fprintf(f2, "%d",eof);
    runCount++;
    break;
   }
   else
   {
    fprintf(f2, "%d %d %d",current,eor,eof);
    fprintf(f1, "%d",eof);
    runCount++;
    break;
   }
  }
  else
  {
   if(current>next)
   {
    if(switchFlag==1)
    {
     fprintf(f1, "%d %d ", current, eor);
     runCount++;
     switchFlag=2;
    }
    else
    {
     fprintf(f2, "%d %d ", current, eor);
     runCount++;
     switchFlag=1;
    }
   }
   else
   {
    if(switchFlag==1)
    {
        fprintf(f1, "%d ", current);
    }
    else
    {
        fprintf(f2, "%d ", current);
    }

   }
  }

  current = next;
 }

 fclose(d);
 fclose(f1);
 fclose(f2);

 return runCount;
}

Merging Runs
After marking runs in the raw data and distributing it into two files, the next step is to merge them and put them back into a file. We pick an element from F1 and F2 each, place the smaller in F0 and advance in the file of which element is placed. If eor is encountered in a file, then copy the remaining elements from the run of the other file. E.g we are having files F1 and F2 as follows.

F1: 76 | 5, 15, 20, 29, 31, 37, 41 | 49, 91 | 76 | EOF
F2: 53 | 40, 50 | 61, 81 | 1, 2, 3, 4, 5, 6 | EOF

Compare 76 and 53; 53<76; 
write 53 in F0; 
advance in F2; 
eor encountered; 
Copy 56 in F0; 
Mark eor; 
Take next elements 5 and 40; 
5<40;
write 5 in F0;
advance in F1;
15<40;
write 15 in F0;
and so on till eof in any of the file is encountered. After that copy the remaining runs from the other file as it is in F0.

Finally F0 will be having following data.
F0: 53, 76 | 5, 15, 20, 29, 31, 37, 40, 41, 50 | 49, 61, 81, 91 | 1, 2, 3, 4, 5, 6, 76 | EOF

The algorithm for merging runs from files F1 and F2 and placing them in F0 is as follows.
1. runCount=0;
2. Rewrite(F0)
3. Reset(F1)
4. Reset(F2)
5. Read(e1, F1)
6. Read(e2, F2)
7. While (e1 != eof and e2 != eof)
     While (e1 != eor and e2 != eor)
        If (e1<e2)
          Write(e1, F0)
          Read(e1, F1)
        Else
          Write(e2, F0)
          Read(e2, F2)
        End if
     End While
  
     If (e1==eor)
        Copy remaining elements of the run from F2 in F0
     Else
        Copy remaining elements of the run from F1 in F0
     End if

     Write(eor, F0)
     Runcount++

     Read(e1, F1)
     Read(e2, F2)
8. End While
9. If(e1==eof)
     While (e2 != eof)
        Write(e2,F0)
        If(e2==eor) runCount++;
        Read(e2,F2)
     End While
   Else if(e2==eof)
     While (e1 != eof)
        Write(e1,F0)
        If(e1==eor) runCount++;
        Read(e1,F1)
     End While
   End if
10. Mark EOF in S0
11. Return runCount

<A sub procedure in C for merging runs>

mergeRuns()
{
 int e1,e2;
 int runCount=0;

 f1 = fopen("file1.txt","r");
 f2 = fopen("file2.txt","r");
 d = fopen("File0.txt","w");

 fscanf(f1,"%d",&e1);
 fscanf(f2,"%d",&e2);

 while (e1!=eof && e2!=eof)
 {
  while(e1!=eor && e2!=eor)
  {
   if(e1<e2)
   {
    fprintf(d,"%d ",e1);
    fscanf(f1,"%d",&e1);
   }
   else
   {
    fprintf(d,"%d ",e2);
    fscanf(f2,"%d",&e2);
   }
  }

  if(e1==eor)
  {
   while (e2!=eor)
   {
    fprintf(d, "%d ", e2);
    fscanf(f2, "%d", &e2);
   }
  }
  else if(e2==eor)
  {
   while (e1!=eor)
   {
    fprintf(d, "%d ", e1);
    fscanf(f1, "%d", &e1);
   }
  }

  fprintf(d, "%d ", eor);
  runCount++;

  fscanf(f1,"%d",&e1);
  fscanf(f2,"%d",&e2);
 }
 if(e1==eof)
 {
  while (e2!=eof)
  {
   fprintf(d, "%d ", e2);
   if(e2==eor) runCount++;
   fscanf(f2, "%d", &e2);
  }
 }
 else if(e2==eof)
 {
  while (e1!=eof)
  {
   fprintf(d, "%d ", e1);
   if(e1==eor) runCount++;
   fscanf(f1, "%d", &e1);
  }
 }

 fprintf(d,"%d",eof);

 fclose(f1);
 fclose(f2);
 fclose(d);

 return runCount;
}

This process of merge and distribute continues till the number of runs in file F0 become 1. At this time the data is completely sorted.

If we start with two files each having runs = N; then after 1 merge and distribute each file will have N/2 runs. After another merge and distribute each file will have N/4 runs. This continues till the run count becomes 1.

Hence for N runs the number of passes, P = log2N Similarly if we know the passes P then number of runs N will be 2P-1 < N <= 2P.


Finally, a complete program in C to demonstrate file sorting using two source and one destination.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

#define eor -1
#define eof -2

FILE *f1, *f2, *d;

markRuns();
mergeRuns();
void distributeRuns();

void main()
{

     markRuns();
     distributeRuns();

     while(mergeRuns()!=1)
     {
        distributeRuns();
     }

     printf("File Sorted....");
     getch();
}


markRuns()
{
 int runCount=0;
 int current, next;

 if( (d = fopen("Source.txt", "r")) == NULL)
 {
  printf("Source file not found.");
  exit(1);
 }

 f1 = fopen("File0.txt","w");

 fscanf(d,"%d",¤t);

 while(1)
 {
  fscanf(d, "%d", &next);

  if(next==eof)
  {
     fprintf(f1, "%d %d %d",current,eor,eof);
     runCount++;
     break;
  }
  else
  {
   if(current>next)
   {
    fprintf(f1, "%d %d ", current, eor);
    runCount++;
   }
   else
   {
    fprintf(f1, "%d ", current);
   }
  }

  current = next;
 }

 fclose(d);
 fclose(f1);
 fclose(f2);

 return runCount;
}

void distributeRuns()
{
 int switchFlag=1;
 int e;

 f1 = fopen("File1.txt", "w");
 f2 = fopen("File2.txt", "w");
 d = fopen("File0.txt", "r");

 fscanf(d,"%d",&e);

 while (e!=eof)
 {
  if(switchFlag==1)
  {
   fprintf(f1, "%d ", e);
   if(e==eor) switchFlag=2;
  }
  else
  {
   fprintf(f2, "%d ", e);
   if(e==eor) switchFlag=1;
  }

  fscanf(d,"%d",&e);
 }

 fprintf(f1, "%d",eof);
 fprintf(f2, "%d",eof);

 fclose(d);
 fclose(f1);
 fclose(f2);
}

mergeRuns()
{
 int e1,e2;
 int runCount=0;

 f1 = fopen("file1.txt","r");
 f2 = fopen("file2.txt","r");
 d = fopen("File0.txt","w");

 fscanf(f1,"%d",&e1);
 fscanf(f2,"%d",&e2);

 while (e1!=eof && e2!=eof)
 {
  while(e1!=eor && e2!=eor)
  {
   if(e1<e2)
   {
    fprintf(d,"%d ",e1);
    fscanf(f1,"%d",&e1);
   }
   else
   {
    fprintf(d,"%d ",e2);
    fscanf(f2,"%d",&e2);
   }
  }

  if(e1==eor)
  {
   while (e2!=eor)
   {
    fprintf(d, "%d ", e2);
    fscanf(f2, "%d", &e2);
   }
  }
  else if(e2==eor)
  {
   while (e1!=eor)
   {
    fprintf(d, "%d ", e1);
    fscanf(f1, "%d", &e1);
   }
  }

  fprintf(d, "%d ", eor);
  runCount++;

  fscanf(f1,"%d",&e1);
  fscanf(f2,"%d",&e2);
 }
 if(e1==eof)
 {
  while (e2!=eof)
  {
   fprintf(d, "%d ", e2);
   if(e2==eor) runCount++;
   fscanf(f2, "%d", &e2);
  }
 }
 else if(e2==eof)
 {
  while (e1!=eof)
  {
   fprintf(d, "%d ", e1);
   if(e1==eor) runCount++;
   fscanf(f1, "%d", &e1);
  }
 }

 fprintf(d,"%d",eof);

 fclose(f1);
 fclose(f2);
 fclose(d);

 return runCount;
}

Sunday, 29 April 2012

Comparative Study of Array Sorting Techniques


----------------------------------------------------------
Algorithm       |    Comparisons     |    Moves
----------------------------------------------------------

----------------------------------------------------------
DataSet 1: 1    2    3    4    5    6    7    8    9    10  

Insertion Sort  |    45         |    0
Selection Sort  |    45         |    0
Bubble Sort     |    45         |    0
EEBubble Sort   |    9          |    0
Shaker Sort     |    9          |    0
Shell Sort      |    62         |    0
Heap Sort       |    80         |    90
Quick Sort      |    25         |    0

----------------------------------------------------------
DataSet 2: 10   9    8    7    6    5    4    3    2    1   

Insertion Sort  |    9          |    54
Selection Sort  |    45         |    15
Bubble Sort     |    45         |    135
EEBubble Sort   |    45         |    135
Shaker Sort     |    45         |    135
Shell Sort      |    62         |    39
Heap Sort       |    67         |    63
Quick Sort      |    25         |    15

----------------------------------------------------------
DataSet 3: 10   1    2    3    4    5    6    7    8    9   

Insertion Sort  |    45         |    18
Selection Sort  |    45         |    27
Bubble Sort     |    45         |    27
EEBubble Sort   |    17         |    27
Shaker Sort     |    17         |    27
Shell Sort      |    62         |    27
Heap Sort       |    71         |    81
Quick Sort      |    45         |    27

----------------------------------------------------------
DataSet 4: 10   2    3    4    5    6    7    8    9    1   

Insertion Sort  |    37         |    26
Selection Sort  |    45         |    3
Bubble Sort     |    45         |    51
EEBubble Sort   |    45         |    51
Shaker Sort     |    24         |    51
Shell Sort      |    57         |    41
Heap Sort       |    75         |    81
Quick Sort      |    25         |    3

----------------------------------------------------------
DataSet 5: 10   1    3    4    5    6    7    8    9    2   

Insertion Sort  |    38         |    25
Selection Sort  |    45         |    6
Bubble Sort     |    45         |    48
EEBubble Sort   |    45         |    48
Shaker Sort     |    24         |    48
Shell Sort      |    57         |    38
Heap Sort       |    75         |    78
Quick Sort      |    25         |    6

----------------------------------------------------------
DataSet 6: 2    1    4    3    6    5    8    7    10   9   

Insertion Sort  |    45         |    10
Selection Sort  |    45         |    15
Bubble Sort     |    45         |    15
EEBubble Sort   |    17         |    15
Shaker Sort     |    17         |    15
Shell Sort      |    62         |    15
Heap Sort       |    78         |    87
Quick Sort      |    23         |    15

Quick Sort in Java

import java.io.*;

class QuickSortDemo 
{
 static int[] a;
 static int c=0,m=0; //variables to keep track of comparisons and moves

 public static void swap(int x, int y)
 {
  int temp = a[x];
  a[x] = a[y];
  a[y] = temp;
  m+=3;
 }

 public static void quickSort(int lb, int ub)
 {
  if(lb>=ub)
   return;

  int down = lb;
  int up = ub;
  int pivot_index = findPivotIndex(lb,ub);

  while(down<up)
  {   
   while(a[down]<=a[pivot_index] && down<up)
   {
    c++;
    down++;
   }
   
   while(a[up]>a[pivot_index])
   {
    c++;
    up--;
   }

   if(down<up)
    swap(down,up);
  }

  if(pivot_index!=up)
   swap(pivot_index,up);

  quickSort(lb,up-1);
  quickSort(up+1,ub);
 }

 public static int findPivotIndex(int lb, int ub)
 {
  int x1=a[lb];
  int x2=a[(lb+ub)/2];
  int x3=a[ub];

  if(x1>x2 && x1<x3 || x1<x2 && x1>x3)
   return lb;

  if(x2>x1 && x2<x3 || x2<x1 && x2>x3)
   return (lb+ub)/2;

  if(x3>x2 && x3<x1 || x3<x2 && x3>x1)
   return ub;

  return lb;
 }

 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   a = new int[element.length];

   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.print(a[i]+"\t");
   }  
     
   quickSort(0,a.length-1); //call to quick Sort  
   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.print(a[i]+"\t");
   }

   System.out.println("\n\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Heap Sort with left curtailment in Java (Best)

import java.io.*;

class HeapSortLC 
{
 static int[] a;
 static int limit;
 static int constant=1;
 static int c=0,m=0; //variables to keep track of comparisons and moves

 public static void reHeapLightBubble(int k)
 {  
  if( 2*k+constant > a.length-1)
   return;

  if( 2*k+(constant+1) > a.length-1)
  {
   c++;
   if(a[k]>a[2*k+constant])
   {
    swap(k,2*k+constant);
    reHeapLightBubble(2*k+constant);  
   }
   return;
  }
  
  c+=2;

  if(a[2*k+constant]<a[k] || a[2*k+(constant+1)]<a[k])
  {
   c++;
   if(a[2*k+constant]<a[2*k+(constant+1)])
   {
    swap(k,2*k+constant);
    reHeapLightBubble(2*k+constant);
   }
   else
   {
    swap(k,2*k+(constant+1));
    reHeapLightBubble(2*k+(constant+1));
   }
   return;
  }
 }

 public static void swap(int x, int y)
 {
  int temp = a[x];
  a[x] = a[y];
  a[y] = temp;
  m+=3;
 }

 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   a = new int[element.length];

   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.print(a[i]+"\t");
   }  
     
   //Main logic of heap sort with left curtailment     

   for(int i=a.length-1; i>=0; i--)
   {
     reHeapLightBubble(i);
   }

   constant--;

   for(limit=1; limit<a.length-1; limit++)
   {
    reHeapLightBubble(limit);
    constant--;
   }
   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.print(a[i]+"\t");
   }

   System.out.println("\n\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Heap Sort with Partial Heaping in Java

import java.io.*;

class HeapSort 
{
 static int[] a;
 static int limit;
 static int c=0,m=0; //variables to keep track of comparisons and moves

 public static void reHeap(int k)
 {  
  if( 2*k+1 > limit)
   return;

  if( 2*k+2 > limit)
  {
   c++;
   if(a[k]<a[2*k+1])
   {
    swap(k,2*k+1);
    reHeap(2*k+1);  
   }
   return;
  }
  
  c+=2;
  if(a[2*k+1]>a[k] || a[2*k+2]>a[k])
  {
   c++;
   if(a[2*k+1]>a[2*k+2])
   {
    swap(k,2*k+1);
    reHeap(2*k+1);
   }
   else
   {
    swap(k,2*k+2);
    reHeap(2*k+2);
   }
   return;
  }
 }

 public static void swap(int x, int y)
 {
  int temp = a[x];
  a[x] = a[y];
  a[y] = temp;
  m+=3;
 }

 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   a = new int[element.length];

   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.print(a[i]+"\t");
   }  
     
   //Main logic of heap sort with partial heaping
   limit=a.length-1;
   reHeap(limit);
   swap(0,limit);
   
   limit--;

   for(; limit>0; limit--)
   {
    reHeap(0);
    swap(0,limit);
   }
   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.print(a[i]+"\t");
   }

   System.out.println("\n\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Heap Sort in Java

import java.io.*;

class HeapSort 
{
 static int[] a;
 static int limit;
 static int c=0,m=0; //variables to keep track of comparisons and moves

 public static void reHeap(int k)
 {  
  if( 2*k+1 > limit)
   return;

  if( 2*k+2 > limit)
  {
   c++;
   if(a[k]<a[2*k+1])
   {
    swap(k,2*k+1);
    reHeap(2*k+1);  
   }
   return;
  }
  
  c+=2;
  if(a[2*k+1]>a[k] || a[2*k+2]>a[k])
  {
   c++;
   if(a[2*k+1]>a[2*k+2])
   {
    swap(k,2*k+1);
    reHeap(2*k+1);
   }
   else
   {
    swap(k,2*k+2);
    reHeap(2*k+2);
   }
   return;
  }
 }

 public static void swap(int x, int y)
 {
  int temp = a[x];
  a[x] = a[y];
  a[y] = temp;
  m+=3;
 }

 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   a = new int[element.length];


   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.print(a[i]+"\t");
   }  

     
   //Main logic of heap sort
   
   for(limit=a.length-1; limit>0; limit--)
   {
    for(int i=limit; i>=0; i--)
     reHeap(i);

    swap(0,limit);
   }
   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.print(a[i]+"\t");
   }

   System.out.println("\n\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Shell Sort in Java

import java.io.*;

class ShellSort 
{
 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   int[] a = new int[element.length];


   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.print(a[i]+"\t");
   }

   int c=0,m=0; //variables to keep track of comparisons and moves

   //Skips for shell sort   
   System.out.print("\nEnter number of skips (Shell Sort): ");   

   int[] skips = new int[Integer.parseInt(br.readLine())];
   
   System.out.println("Enter skips (the last skip value must be 1): ");
   for(int i=0; i<skips.length; i++)
   {
    skips[i] = Integer.parseInt(br.readLine());
   }

   
   //Main logic of shell sort
   
   for(int x=0; x<skips.length; x++)
   {
    int gap=skips[x];

    for(int start=0; start<gap; start++)
    {
     for(int i=gap+start;i<a.length;i+=gap)
     {
      for(int j=start; j<i; j+=gap)
      { 
       c++;
       if(a[i]<a[j])
       {
        int temp = a[i];

        for(int k=i; k>j; k-=gap)
        {
         m++;
         a[k]=a[k-gap];
        }

        m++;
        a[j] = temp;
        break;
       }
      } 
     }   
    }    
   }  
   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.print(a[i]+"\t");
   }

   System.out.println("\n\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Shaker Sort in Java

import java.io.*;

class ShakerSort 
{
 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   int[] a = new int[element.length];


   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.print(a[i]+"\t");
   }

   int c=0,m=0; //variables to keep track of comparisons and moves

   
   //Main logic of shaker sort
   
  
   for(int pass=0; pass<a.length/2; pass++)
   {
    boolean flag=true;

    for(int j=pass; j<a.length-pass-1; j++)
    { 
     c++;
     if(a[j]>a[j+1])
     {
      int temp = a[j];
      a[j] = a[j+1];
      a[j+1] = temp;
      m+=3;
      flag=false;
     }
    }

    if(flag)
     break;

    flag=true;

    for(int j=a.length-(pass+2); j>pass; j--)
    {
     c++;
     if(a[j]<a[j-1])
     {
      int temp=a[j];
      a[j]=a[j-1];
      a[j-1]=temp;
      m+=3;
      flag=false;
     }
    }

    if(flag)
     break;
   }

   
   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.print(a[i]+"\t");
   }

   System.out.println("\n\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Bubble Sort with Early Exit in Java

import java.io.*;

class BubbleSort 
{
 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   int[] a = new int[element.length];


   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.print(a[i]+"\t");
   }

   int c=0,m=0; //variables to keep track of comparisons and moves

   
   //Main logic of bubble sort with early exit
   

   for(int pass=0; pass<a.length; pass++)
   {
    boolean flag=true;

    for(int j=0; j<a.length-pass-1; j++)
    {
     c++;
     if(a[j]>a[j+1])
     {
      int temp = a[j];
      a[j] = a[j+1];
      a[j+1] = temp;
      m+=3;
      flag=false;
     }
    }

    if(flag)
     break;
   }
   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.print(a[i]+"\t");
   }

   System.out.println("\n\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Selection Sort in Java

import java.io.*;

class SelectionSort 
{
 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   int[] a = new int[element.length];


   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.print(a[i]+"\t");
   }

   int c=0,m=0; //variables to keep track of comparisons and moves

   
   //Main logic of selection sort

   for(int i=0; i<a.length-1; i++)
   {
    int min=i;
    for(int j=i+1; j<a.length; j++)
    {
     c++;
     if(a[min]>a[j])
      min=j;
    }

    if(min!=i)
    {
     int temp = a[min];
     a[min] = a[i];
     a[i] = temp;
     m+=3;
    }
   }
   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.print(a[i]+"\t");
   }

   System.out.println("\n\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Insertion Sort in Java

import java.io.*;

class InsertionSort 
{
 public static void main(String[] args) 
 {
  try
  {
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Enter name of the source file: ");
   FileReader fr =new FileReader(br.readLine());

   char[] buffer = new char[2048];
   int len = fr.read(buffer);

   String data = new String(buffer,0,len);

   String[] element = data.split(",");

   int[] a = new int[element.length];


   System.out.println("\n\nBefore Sorting: ");

   for(int i=0; i<a.length; i++)
   {
    a[i] = Integer.parseInt(element[i]);
    System.out.println(a[i]);
   }

   int c=0,m=0; //variables to keep track of comparisons and moves


   //Main logic of insertion sort
   for(int i=1; i<a.length; i++)
   {
    for(int j=0;j<i; j++)
    {
     c++;
     if(a[j]>a[i])
     {
      int temp = a[i];
      for(int k=i; k>j; k--)
      {
       a[k] = a[k-1];
       m++;
      }
      
      a[j] = temp;
      m++;      
      break;
     }
    }
   }

   
   System.out.println("\n\nAfter Sorting: ");

   for(int i=0; i<a.length; i++)
   {   
    System.out.println(a[i]);
   }

   System.out.println("\nComparisons = " + c + "\tMoves = " + m);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Do you like this article?