Brief analysis of direct insertion sort and half insertion sort

  • 2020-04-02 02:03:58
  • OfStack

Let's take a look at the example, insert the data one by one into a list, and then the list will be sorted

Note: this list is incrementing, and the memory space is allocated, but the actual data is not populated, as shown in the following code:


int InsertSort(MergeType *L, int data)
{
 int j;
 if (!L->len)
 {
  L->elem[++L->len] = data;
  return 0;
 }
 for (j = L->len-1; j >= 0; --j)
 {
  if (data < L->elem[j])
  {
   L->elem[j+1] = L->elem[j];
  }
  else
  {
   L->elem[j+1] = data;
   L->len++;
   break;
  }
 }
 return 0;
}

The test case code is as follows:


#define  LISTLEN 10 
 MergeType pList;
 MergeType pT;  
 pList.elem = (int*)malloc(sizeof(int)*LISTLEN);
 ScanfList(&pList);
 pList.len  = LISTLEN;
 pList.size = LISTLEN;
 
 pT.elem = (int*)malloc(sizeof(int)*LISTLEN); 
 pT.len = 0;
 pT.size = LISTLEN;
 memset(pT.elem, 0, LISTLEN*sizeof(int));
 for (int i = 0; i < LISTLEN; i++ )
 {
  InsertSort(&pT, pList.elem[i]);
 }
 PrintList(&pT);

 free(pList.elem);
 free(pT.elem);
 pList.elem = NULL;
 pT.elem = NULL;

Other functions and code to define please refer to:

Direct insertion sort

Core idea: is to insert a record into the sorted ordered table, from which a new, the number of records increased by 1 ordered table, that is, the increasing order of each data, each data into the previously sorted position. Look at the code below


int InsertSort(MergeType* L)
{
 int i, j = 0;
 int nCompKey;
 if (!L->elem || !L->len) return -1;

 if (L->elem && (L->len==1)) return 0;
 for ( i = 1; i < L->len; i++) 
 {
  if (L->elem[i] < L->elem[i-1])  
  {
   nCompKey = L->elem[i];
   L->elem[i] = L->elem[i-1];   
   //move elements back
   for (j = i-2; j >= 0 && nCompKey < L->elem[j]; --j) 
   {
    L->elem[j+1] = L->elem[j];
   }
   L->elem[j+1] = nCompKey;
  }
 }
 return 0;
}

Here, we start from the second data and compare whether the current data is less than the previous number. If the current data is less than the previous number, we insert the current data into the previous queue. During the insertion into the previous data, we move the data

Note the complexity of time:

Total number of comparisons =1+2+...... + (I + 1-2 + 1) +... + (n - 2 + 1) = n * (n - 1) / 2 = O (n ^ 2)

Total movement =2+3+...... + (2 + I - 1) +... + n = (n + 2) * (n - 1) / 2 = O (n ^ 2)

Of course, there is also the complexity of space: the storage space of a variable is used as the temporary space for moving data


Here, in the process of moving, the complexity of code understanding can be reduced, but the number of times of comparison will be increased in each process of data comparison, as shown in the following code:


 ...
 if (L->elem[i] < L->elem[i-1])  
 {
  nCompKey = L->elem[i];
  
  for (j = i-1; j >= 0 && L->elem[j] > nCompKey; --j) 
  {
   L->elem[j+1] = L->elem[j];
  }
  L->elem[j+1] = nCompKey; 
 }
 ...

In the process of inserting data, in fact, the previous data have been sorted, at this time, one by one to find, must find more times, if the use of half-cut search algorithm can reduce the number of times, as follows



int BInsertSort(MergeType *L)
{
 int i, j;
 int low, high, mid;
 int nCompKey;
 for (i = 1; i <= L->len - 1; i++ )
 {
  nCompKey = L->elem[i];
  low = 0;
  high = i - 1;

  
  while(low <= high) 
  {
   mid = (low + high)/2;
   if ( nCompKey > L->elem[mid] )
   {
    low = mid + 1;
   }
   else
   {
    high = mid -1;
   }
  }
  
  for (j = i-1; j >= high+1; j-- ) 
  {
   L->elem[j+1] = L->elem[j]; 
  }
  
  L->elem[high+1] = nCompKey;
 }
 return 0;
}

For the specific reason, please refer to the above comment, why high+1 is used here, but at this time, the position of high and low is only one position different, it will break out of the while loop, please see the following improvement


#if 0
  for (j = i-1; j >= high+1; j-- ) 
  {
   L->elem[j+1] = L->elem[j]; 
  }
  L->elem[high+1] = nCompKey;
#else
  for (j = i-1; j >= low; j-- ) 
  {
   L->elem[j+1] = L->elem[j]; 
  }
  L->elem[low] = nCompKey;
#endif
...


Related articles: