The improvement of bubble algorithm is realized

  • 2020-04-02 02:04:02
  • OfStack

The idea of bubble sort algorithm:

First, the keyword of the first record is compared with the second keyword, and if it is in reverse order, the two records are exchanged.
The keywords for the second record and the third record are then compared until the n-1 record is compared with the NTH record, after which the largest element sinks to the bottom.
The second sort is then performed, and the same 1, 2 operations are performed on the first n-1 records. The result is that the records with the largest keyword are placed in the n-1 position.
Sort the I th time in turn, and do the same 1 and 2 for the first n-i records, until there is no comparison in the first time.
Take a look at the basic bubble algorithm:


int BubbleSort(MergeType* L)
{
 int i, j;
 for (i = 0; i <= L->len-1; i++)
 {  
  for (j = 0; j < L->len-1-i; j++)
  {
   if (L->elem[j+1] < L->elem[j])
   {
    SWAP(L->elem[j+1], L->elem[j] ); 
   }
  } 
 }
 return 0;
}

The MergeType type here is as follows:


typedef struct _SQLIST{
    int* elem;
    int len;   //The actual length
    int size;  //Allocate space
}SqList, *pSqList;
typedef _SQLIST MergeType;

The idea is to pick the largest number at a time and sink to the bottom until there is no data to compare.

First, calculate its time complexity. Here, the worst-case scenario:

(n-1) + (n-2) +... Plus 1 plus 0 is n times n minus 1 over 2   = O (n ^ 2)

The best case is that it's sorted and there's no comparison
The first thing you'll see is one of its drawbacks: frequent swapping of elements. How to avoid it can be stored in a suitable location by simplifying algorithm one:


int BubbleSortEx(MergeType* L)
{
 int i = 0, j = 0;
 int max, temp;
 for (i = 0; i <= L->len-1; i++)
 {  
  temp = L->elem[0];
  max = 0;
  for (j = 1; j < L->len-i; j++)
  {   
   if (L->elem[j] > temp)
   {
    temp = L->elem[j];
    max = j;
   }
  }
  //printf("%d:%d n", max, temp);
  swap(L->elem[L->len-1-i], L->elem[max] );   
 }
 return 0;
}

See here every time still need to carry out the assignment operation frequently, of course, it is only trivial, but the assignment will also increase the CPU execution time, so streamline algorithm 2:


int BubbleSortEx(MergeType* L)
{
 int i, j , max;
 for (int i = 0; i <= L->len-1; i++)
 {  
  max = 0;
  for (j = 1; j < L->len-i; j++)
  {   
   if (L->elem[j] > L->elem[max])
   {
    max = j;
   }
  }
  //printf("%d:%d n", max, L->elem[max]);
  swap(L->elem[L->len-1-i], L->elem[max] );   
 }
 return 0;
}

The two swap here are not the same, of course, you can also use the same, see the following specific implementation:


#define SWAP(a, b) 
{                 
 int temp = (a); 
 (a) = (b);        
 (b) = temp;     
}


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

The first is the use of macro substitution, of course, mainly to increase the preprocessing time, mainly with macros will be unexpected errors
The second is the function, which USES a reference to reduce the creation of a copy of the parameter used by the pointer, but the inline is used, so it is replaced

Test procedures:


int PrintList(MergeType *L);
int ScanfList(MergeType *L, const int nScanfType = -1);
int SortTest()
{
 printf("--- %s ---n", __FUNCTION__);
 MergeType pList;
 MergeType pT;  
 pList.elem = (int*)malloc(sizeof(int)*10);
 pList.len  = 10;
 pList.size  = 10;

 ScanfList(&pList); 

 BubbleSortEx(&pList);
 PrintList(&pList);
 free(pList.elem);
 pList.elem = NULL;

 return 0;
}

Data input:


int ScanfList(MergeType *L, const int nScanfType)
{
 if (!L->elem)
 {
  return -1;
 }

 printf("Old Listt: ");

 for (int i = 0; i <= L->len; i++ )
 {
  if( i == L->len )
  {
   printf("n");
   break;
  }
  switch (nScanfType)
  {
  case 0:
   {
    break;
   }
  default:
   L->elem[i] = 11 * i - i * i;
   break;
  }  
  printf("%d ", L->elem[i]);
 }
 return 0;
}

Data output:


int PrintList(MergeType *L)
{ 
 if (!L->elem)
 {
  return -1;
 }

 printf("Sort Listt: ");

 for (int i = 0; i <= L->len; i++ )
 {
  if (i == L->len)
  {
   printf("n");

   break;
  }
  printf("%d ", L->elem[i]);
 }
 return 0;
}


Related articles: