Basic sorting algorithm

Posted by Devil_Banner on Sat, 01 Jan 2022 17:09:09 +0100

Sorting algorithmAverage time complexityWorst time complexitySpatial complexityData object stability
Bubble sortingO( n 2 n^{2} n2)O( n 2 n^{2} n2)O(1)stable
Select sortO( n 2 n^{2} n2)O( n 2 n^{2} n2)O(1)Unstable array and linked list
Insert sortO( n 2 n^{2} n2)O( n 2 n^{2} n2)O(1)stable
Quick sortO(n * l o g 2 n log_{2n} log2n​)O( n 2 n^{2} n2)O( l o g 2 n log_{2n} log2n​)instable
Heap sortO(n * l o g 2 n log_{2n} log2n​)O(n * l o g 2 n log_{2n} log2n​)O(1)instable
Merge sortO(n * l o g 2 n log_{2n} log2n​)O(n * l o g 2 n log_{2n} log2n​)O(n)stable
Shell Sort O(n * l o g 2 n log_{2n} log2n​)O( n 2 n^{2} n2)O(1)instable
Count sortO(n + m)O(n + m)O(n + m)stable
Bucket sortingO(n)O(n)O(m)stable
Cardinality sortO(k * n)O( n 2 n^{2} n2)stable
  • Stable: if a was in front of b and a=b, a will still be in front of b after sorting.
  • Unstable: if a was originally in front of b and a=b, a may appear after b after sorting.
  • Time complexity: the total number of operations on sorting data. Reflect the law of operation times when n changes.
  • Spatial complexity: refers to the measurement of the storage space required for the implementation of the algorithm in the computer. It is also a function of the data scale n.

1. Bubble Sort

  • It repeatedly visits the element column to be sorted, compares two adjacent elements in turn, and exchanges them if the order (such as from large to small, and the initial letter from Z to A) is wrong. The work of visiting elements is repeated until no adjacent elements need to be exchanged, that is, the element column has been sorted.
  • The name of this algorithm comes from the fact that the smaller elements will slowly "float" to the top of the sequence (in ascending or descending order) through exchange, just as the bubbles of carbon dioxide in carbonated drinks will eventually float to the top, so it is called "bubble sorting".

Algorithm implementation

  1. Compare adjacent elements. If the first one is bigger than the second, exchange them.
  2. Do the same for each pair of adjacent elements, from the first pair at the beginning to the last pair at the end. After this step, the last element will be the maximum number.
  3. Repeat the above steps for all elements except the last one.
  4. Continue to repeat the above steps for fewer and fewer elements at a time until no pair of numbers need to be compared.
void bubbleSort(int a[], int n)
{
  int i,j;
  int key = 0;
  for(i = 0 ; i< n - 1; ++i) { 
    key = 0; //Before starting bubbling each time, the initialization key value is 0
    for(j = 0; j < n - i - 1; ++j) {
      if(a[j] > a[j+1]) {
        key=1;
        int tmp = a[j];  //exchange
        a[j] = a[j+1];
        a[j+1] = tmp;
      }
    }
    if (key == 0) //When there is no data exchange, the current data has been sorted
      break;
  }
}

test

void PrintArr (int arr[], int n) //Print array
{
  for (int i = 0; i < n; i++) {
    printf ("%d ",arr[i]);
  }
  printf ("\n");
}

int main (int argc, char *argv[])
{
  int arr[] = {3, 44, 38, 5, 47, 15, 36, 26, 27};
  int len = sizeof(arr)/sizeof(arr[0]);
  int i;

  printf ("Original data:\n");
  PrintArr (arr, len);

  bubbleSort (arr, len); //Bubble sorting
  
  printf ("New data:\n");
  PrintArr (arr, len);
  
  return 0;
}

2. Selection sort

  • A simple and intuitive sorting algorithm.
  • The working principle is: select the smallest (or largest) element from the data elements to be sorted for the first time, store it at the beginning of the sequence, and then find the smallest from the remaining unordered elements (large) elements, and then put them at the end of the sorted sequence. And so on until the number of all data elements to be sorted is zero. Selecting sorting is an unstable sorting method.

Algorithm implementation

  1. Find the smallest (large) element in the unordered sequence and store it at the beginning of the sorted sequence
  2. Continue to find the smallest (large) element from the remaining unordered elements and put it at the end of the sorted sequence
  3. And so on until all elements are sorted
void SelectSort(int arr[], int n) //n is the number of array elements
{
  //Make N-1 round selection
  for(int i = 0; i < n - 1; i++) {
    int min_index = i; 
    //Find the position of the smallest number i
    for(int j = i + 1; j < n; j++) {
      if(arr[j] < arr[min_index]) {
        min_index = j;
      }
    }

    //Place the smallest number i in position i; If it happens, you don't have to exchange
    if( i != min_index) {
      int temp = arr[i];
      arr[i] = arr[min_index];
      arr[min_index] = temp;
    }
  }
}

test

void PrintArr (int arr[], int n) //Print array
{
  for (int i = 0; i < n; i++) {
    printf ("%d ",arr[i]);
  }
  printf ("\n");
}

int main (int argc, char *argv[])
{
  int arr[] = {2, 44, 5, 27, 3, 50, 48};
  int len = sizeof(arr)/sizeof(arr[0]);
  int i;

  printf ("Original data:\n");
  PrintArr (arr, len);

  SelectSort (arr, len); //Bubble sorting
  
  printf ("New data:\n");
  PrintArr (arr, len);
  
  return 0;
}

3. Insertion Sort

  • It is also commonly referred to as direct insertion sorting.
  • It is an effective algorithm for sorting a small number of elements.
  • It is the simplest sort method. Its basic idea is to insert a record into the ordered table, so as to create a new ordered table with the number of records increased by 1. In its implementation process, a double-layer loop is used. The outer loop finds the position to be inserted in the ordered table in front of the current element for all elements except the first element, and moves it [2].

Algorithm implementation

  1. Starting with the first element, the element can be considered to have been sorted
  2. Take out the next element and scan from back to forward in the sorted element sequence
  3. If the element (sorted) is larger than the new element, move the element to the next position
  4. Repeat step 3 until you find a location where the sorted element is less than or equal to the new element
  5. After inserting the new element into this location
  6. Repeat steps 2 to 5
void InsertSort(int a[], int n) //Insert sort function directly
{
  for(int i= 1; i < n; i++){
    if(a[i] < a[i-1]){//If the i-th element is greater than i-1 element, insert it directly; On the contrary, you need to find the appropriate insertion position before inserting.
      int j = i - 1;
      int x = a[i];
      while(j > -1 && x < a[j]){  //The insertion position is found by sequential search. While searching, the elements in the array are moved back to make room for the inserted elements
        a[j+1] = a[j];
        j--;
      }
      a[j+1] = x;      //Insert in the correct position
    }
    PrintArr(a,n,i);//Print the results after each sorting
  }
}

test

//Custom output function
void PrintArr(int arr[], int n ,int i) 
{
  printf("The first%d second: ",i);

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

int main(void)
{
  int arr[] = {3, 44, 38, 5, 44, 4, 19, 50};
  int len = sizeof(arr)/sizeof(arr[0]);
  
  printf ("Original data:\n");
  PrintArr(arr, len, 0);
  printf ("\n");

  InsertSort(arr, len);

  printf ("\n New data:\n");
  PrintArr (arr, len, 0);

  return 0;
}

4. Quick Sort

  • Quicksort is an improvement of bubble sort algorithm.
  • The records to be arranged are separated into two independent parts by one-time sorting. If the keywords of one part of the records are smaller than those of the other part, the records of the two parts can be sorted separately to achieve the order of the whole sequence.

Algorithm implementation

  1. Pick out an element from the sequence, which is called "pivot";
  2. Reorder the sequence. All elements smaller than the benchmark value are placed in front of the benchmark, and all elements larger than the benchmark value are placed behind the benchmark (the same number can be on either side). After the partition exits, the benchmark is in the middle of the sequence. This is called partition operation;
  3. Recursively sorts subsequences that are smaller than the reference value element and subsequences that are larger than the reference value element.


As above, the unordered table {2,3, 44, 38, 5, 47, 15, 36, 26, 27, 46, 4, 19, 50, 48} is quickly sorted:

  1. First, select the keyword of a record from the table as the split point (called "pivot" or fulcrum, generally select the first keyword), for example, select 3;
  2. In the table, those greater than 3 are placed on the right side of 3 and those less than 3 are placed on the left side of 3. It is assumed that the completed unordered table is: {2, 3, 44, 38, 5, 47, 15, 36, 26, 27, 46, 4, 19, 50, 48};
  3. Taking 3 as the fulcrum, the whole unordered table is divided into two parts, namely {2} and {44, 38, 5, 47, 15, 36, 26, 27, 46, 4, 19, 50, 48}. This method continues to sort the two sub tables respectively;
  4. The front molecular table has only {2}, and this part has only one value without sorting; The rear molecular table takes 44 as the fulcrum, and the sorted sub table is {38, 5, 15, 36, 26, 27, 4, 19, 44, 47, 46, 50, 48}. 44 is divided into two sub tables, {38, 5, 15, 36, 26, 27, 4, 19} and {47, 46, 50, 48};
  • Repeat the above steps 2 and 3 until all sorting is completed {2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50};
#define MAX 16
//Structure of a single record
typedef struct {
    int key;
}SqNote;
//Structure of record table
typedef struct {
    SqNote r[MAX];
    int length;
}SqList;
//In this method, in the array of records stored, the position with subscript 0 is marked in time and space, and no records are placed. The records are stored in turn from the position with subscript 1
int Partition(SqList *L,int low,int high)
{
  L->r[0]=L->r[low];
  int pivotkey=L->r[low].key;
  //Until the two pointers meet, the program ends
  while (low<high) {
    //The high pointer moves to the left until a record smaller than the pivotkey value is encountered, and the pointer stops moving
    while (low<high && L->r[high].key>=pivotkey) {
      high--;
    }
    //Directly move the record that is less than the fulcrum pointed by high to the position of the low pointer.
    L->r[low]=L->r[high];
    //The low pointer moves to the right until a record larger than the pivotkey value is encountered, and the pointer stops moving
    while (low<high && L->r[low].key<=pivotkey) {
      low++;
    }
    //Directly move the record pointed to by low that is larger than the fulcrum to the position of the high pointer
    L->r[high]=L->r[low];
  }
  //Add the fulcrum to the exact location
  L->r[low]=L->r[0];
  return low;
}

void QSort(SqList *L,int low,int high)
{
  if (low<high) {
    //Find the location of the fulcrum
    int pivotloc=Partition(L, low, high);
    //Sort the sub table on the left side of the fulcrum
    QSort(L, low, pivotloc-1);
    //Sort the sub table on the right side of the fulcrum
    QSort(L, pivotloc+1, high);
  }
}

void QuickSort(SqList *L){
    QSort(L, 1,L->length);
}

test

int main (void) 
{
  SqList * L = (SqList*)malloc(sizeof(SqList));
  int i;
  int arr[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};

  L->length = sizeof (arr) / sizeof (arr[0]);
  for (i = 0; i < L->length; i++) {
    L->r[i+1].key = arr[i];
  }
  
  printf ("raw data: \n");
  for (i = 0; i < L->length; i++) {
    printf ("%d ",L->r[i+1].key);
  }

  QuickSort(L);
  
  printf ("\n Quick sort:\n");
  for (i = 0; i < L->length; i++) {
    printf("%d ",L->r[i+1].key);
  }
  printf ("\n");

  return 0;
}

5. Heap Sort

  • A sort algorithm designed by using heap data structure.
  • Heap is a structure similar to a complete binary tree and satisfies the nature of heap: that is, the key value or index of a child node is always less than (or greater than) its parent node.

Algorithm implementation

  1. The initial keyword sequence to be sorted (R1,R2,... Rn) is constructed into a large top heap, which is the initial unordered area;
  2. Exchange the top element R[1] with the last element R[n], and a new disordered region (R1,R2,... Rn-1) and a new ordered region (Rn) are obtained, and R[1,2... N-1] < = R[n];
  3. Since the new heap top R[1] may violate the nature of the heap after exchange, it is necessary to adjust the current unordered area (R1,R2,... Rn-1) to a new heap, and then exchange R[1] with the last element of the unordered area again to obtain a new unordered area (R1,R2,... Rn-2) and a new ordered area (Rn-1,Rn). Repeat this process until the number of elements in the ordered area is n-1, and the whole sorting process is completed.
void swap(int *i, int *j) //Array element exchange
{
  *i = *i + *j;
  *j = *i - *j;
  *i = *i - *j;
}
// Heap sorting: (maximum heap, ordered area). Unload the root from the top of the heap and put it in the ordered area before resuming the heap.

void max_heapify(int arr[], int start, int end) {
	//Create parent node indicators and child node indicators
	int dad = start;
	int son = dad * 2 + 1;
	while (son <= end) { //Only when the child node is within the range can the comparison be made
		if (son + 1 <= end && arr[son] < arr[son + 1]) //First compare the indicators of the two child nodes and select the largest one
			son++;
		if (arr[dad] > arr[son]) //If the parent node is larger than the child node, the adjustment is completed, and the function will jump out directly
			return;
		else { //Otherwise, the parent and child contents are exchanged, and then the comparison between child nodes and grandchildren continues
			swap(&arr[dad], &arr[son]);
			dad = son;
			son = dad * 2 + 1;
		}
	}
}

void heap_sort(int arr[], int len) {
	//Initialization, i starting from the last parent node
	for (int i = len / 2 - 1; i >= 0; i--)
		max_heapify(arr, i, len - 1);
	//First, exchange the first element with the previous element that has been arranged, and then adjust it again (the element before the element just adjusted) until the sorting is completed
	for (int i = len - 1; i > 0; i--) {
		swap(&arr[0], &arr[i]);
		max_heapify(arr, 0, i - 1);
	}
}

test

int main() {
	int arr[] = {91, 60, 96, 13, 35, 65, 46, 65, 10, 30, 20, 31, 77, 81, 22};
	int len = (int) sizeof(arr) / sizeof(*arr);
  int i;
 
  printf ("Original data:\n");
  for (i = 0; i < len; i++) {
    printf ("%d ", arr[i]);
  }
  
	heap_sort(arr, len);
	
  printf ("\n Heap sort:\n");
  for (i = 0; i < len; i++)
	  printf ("%d ", arr[i]);
	printf ("\n");

	return 0;
}

6. Merge sort

  • Merge sort is an effective sort algorithm based on merge operation. The algorithm is a very typical application of Divide and Conquer.
  • The ordered subsequences are combined to obtain a completely ordered sequence; That is, each subsequence is ordered first, and then the subsequence segments are ordered. If two ordered tables are merged into one ordered table, it is called 2-way merging.

Algorithm implementation

  1. The input sequence with length n is divided into two subsequences with length n/2;
  2. The two subsequences are sorted by merging;
  3. Merge two sorted subsequences into a final sorting sequence.


For an unordered table with n records, First, each record in the table is an ordered table by default (except that the length of the table is 1), and then merge in pairs to change n ordered tables into ⌈ n/2 ⌉ ordered tables with length of 2 or 1 (for example, 4 small ordered tables are merged into 2 large ordered tables). Continue to merge in pairs until an ordered table with length of n is obtained.

#define  MAX 9
typedef struct{
    int key;
}SqNode;

typedef struct{
    SqNode r[MAX];
    int length;
}SqList;

//Records in SR are divided into two parts: subscripts are ordered from i to m, and subscripts are also ordered from m+1 to n. the function is to combine them into TR array to make the whole record table orderly
void Merge(SqNode SR[],SqNode TR[],int i,int m,int n)
{
  int j,k;
  //Add two parts of records in SR array to TR array in descending order
  for (j=m+1,k=i; i<=m && j<=n; k++) {
    if (SR[i].key<SR[j].key) {
      TR[k]=SR[i++];
    } else {
       TR[k]=SR[j++];
    }
  }

  //Copy the remaining records larger than the current tr array to the last position of the TR array
  while(i<=m) {
    TR[k++]=SR[i++];
  }
  while (j<=n) {
    TR[k++]=SR[j++];
  }
}

void MSort(SqNode SR[],SqNode TR1[],int s,int t)
{
  SqNode TR2[MAX];
  //Recursive exit
  if (s==t) {
    TR1[s]=SR[s];
  } else {
      int m=(s+t)/2;//Each recursion divides the records in the record table equally until each record forms a table
      MSort(SR, TR2, s, m);//Sort the records in the separated first half of the table
      MSort(SR,TR2, m+1, t);//Merge and sort the records in the second half of the table
      Merge(TR2,TR1,s,m, t);//Finally, the records in the first half and the second half are sorted uniformly
  }
}

//Merge sort
void MergeSort(SqList *L)
{
  MSort(L->r,L->r,1,L->length);
}

test

int main()
{
  SqList * L=(SqList*)malloc(sizeof(SqList));
  int arr[] = {26, 27, 2, 46, 4, 19, 50, 48};
  int i;
  L->length = sizeof (arr) / sizeof (arr[0]);

  for (i = 0; i < L->length; i++) {
    L->r[i+1].key = arr[i];
  }

  printf ("raw data: \n");
  for (i = 0; i < L->length; i++) {
    printf ("%d ",L->r[i+1].key);
  }

  MergeSort(L);
  
  printf ("\n Merge sort:\n");
  for (i = 0; i < L->length; i++) {
    printf("%d ",L->r[i+1].key);
  }
  printf ("\n");

  return 0;
}

7. Shell Sort

  • In 1959, Shell invented the first sorting algorithm to break through O(n2), which is an improved version of simple insertion sorting. It differs from insert sort in that it preferentially compares elements that are far away.
  • Hill sort is to group records by certain increment of subscript, and sort each group by direct insertion sort algorithm; As the increment decreases, each group contains more and more keywords. When the increment decreases to 1, the whole file is just divided into one group, and the algorithm terminates.
  • Hill sort is also called narrowing increment sort.
    Algorithm idea:

Algorithm implementation

First, divide the whole record sequence to be sorted into several subsequences for direct insertion sorting. The specific algorithm description is as follows:

  1. Select an incremental sequence t1, t2,..., tk, where ti > TJ, tk=1;
  2. Sort the sequence k times according to the number of incremental sequences k;
  3. For each sorting, the sequence to be sorted is divided into several subsequences with length m according to the corresponding increment ti, and each sub table is directly inserted and sorted. Only when the increment factor is 1, the whole sequence is treated as a table, and the table length is the length of the whole sequence.

void ShellSort(int arr[], int len) 
{
  int i, h, j;
  h = 1;
  while (h < len / 3) {
    h = 3 * h + 1;
  }
  while (h >= 1) {
    for (i = h; i < len; i++) {
      for (j = i; j >= h && arr[j] < arr[j - h]; j -= h) {
        swap(&arr[j], &arr[j - h]); //Swap array elements
      }
    }
    h = h / 3;
  }
}

test

void swap(int *i, int *j) //Array element exchange
{
  *i = *i + *j;
  *j = *i - *j;
  *i = *i - *j;
}

int main (void)
{
  int arr[] = {84, 83, 88, 87, 61, 50, 70, 60, 80, 99};
  int len = sizeof(arr)/sizeof(arr[0]);
  int i;
  
  printf ("Original data:\n");
  for (i = 0; i < len; i++) {
    printf ("%d ", arr[i]);
  }
  
  ShellSort(arr, len);

  printf ("\n New data:\n");
  for (i = 0; i < len; i++) {
    printf ("%d ", arr[i]);
  }
  printf ("\n");

  return 0;
}

8. Counting Sort

Counting sort is not a sort algorithm based on comparison. Its core is to convert the input data values into keys and store them in the additional array space. As a sort with linear time complexity, count sort requires that the input data must be integers with a certain range.

Algorithm implementation

  1. Introduce a temporary array.
  2. For element i, a number smaller than i is calculated to determine the position of i.
  3. The calculation is repeated and the array is filled.

void count_sort_normal(int source_array[], int source_array_length)
{
  int i, j, k;

  // Defines a temporary array with an initial value of 0
  int* tmp_group = (int*)malloc(sizeof(int) * source_array_length);

  // The index of the target element in an ordered array
  int target_index;

  // Number of repetitions of the target element
  int target_num;

  for (i = 0; i < source_array_length; i++) {
    target_index = 0;
    target_num = 0;

    for (j = 0; j < source_array_length; j++) {
      // Traverse to get the index of the target element
      if (source_array[j] < source_array[i]) {
        target_index++;
      } else { // Count repetitions
          if (source_array[j] == source_array[i]) {
            target_num++;
          }
      }
    }

    // Fill the temporary array. When the value in the temporary array is 0, it indicates that it is not filled. When the current element is 0, no padding is required.
    if (tmp_group[target_index] == 0 && source_array[i] !=0 ) {
      // Fill based on number of repetitions
      for (k = 1; k <= target_num; k++) {
        tmp_group[target_index] = source_array[i];
        target_index++;
      }
    }
  }

  // Replace the original array
  for (i = 0; i < source_array_length; i++) {
    source_array[i] = tmp_group[i];
  }
}

test

void printf_arr(int arr[],int size) //Print array
{
  int i = 0;
  for (; i < size; i++) {
    printf("%d ", arr[i]);
  }
  printf ("\n");
}

int main (void)
{
  int arr[] = {2, 3, 8, 7, 1, 2, 2, 2, 7, 3, 9, 8, 2, 1, 4, 2, 4, 6, 9, 2};
  int len = sizeof(arr) / sizeof(arr[0]);

  count_sort_normal (arr, len);

  printf_arr(arr, len);

  return 0;
}

9. Bucket Sort

Bucket sorting is an upgraded version of counting sorting. It makes use of the mapping relationship of the function. The key to efficiency lies in the determination of the mapping function. Working principle of bucket sort: assuming that the input data is uniformly distributed, divide the data into a limited number of buckets, and sort each bucket separately (it is possible to use another sorting algorithm or continue to use bucket sorting recursively).

Algorithm implementation

Put the elements with value i into bucket i, and finally pour out the elements in the bucket in turn.

  1. Set a quantitative array as an empty bucket.
  2. Search the sequence and put the items in the corresponding bucket one by one.
  3. Sort each bucket that is not empty.
  4. Put items back into the original sequence from a bucket that is not empty.
#define BUCKET_SIZE 10 / / storage size of a single bucket

typedef struct node {
	int num;
	struct node *next;
}KeyNode;

int ReturnCount (int number)  //Return digits
{
	int count = 0; 

	while(number) {
			number = number / 10;//Remove the last digit of the number each time
			count++;//Cycle once counter + 1
	}
  
  return count;
}

void bucket_sort(int arr[], int size) 
{
	int i,j;

  //This is an array of structure pointers. There are pointers in the array, and memory should be allocated. The size allocated to the structure pointer array is bucket_ Memory space of size
	//Use a two-dimensional pointer to represent a two-dimensional array and dynamically allocate memory space
	KeyNode **bucket_num = (KeyNode **)malloc(BUCKET_SIZE * sizeof(KeyNode*));    //Allocate space for rows

	for(i = 0; i < BUCKET_SIZE; i++) {
		bucket_num[i] = (KeyNode*)malloc(sizeof(KeyNode));      //Allocate memory space for each bucket and space for columns
		bucket_num[i]->num = 0;   //Record the quantity in the current bucket, and the quantity in the initialization bucket is 0
		bucket_num[i]->next = NULL;   //Initializes null for the structure pointer variable in the structure
	}
	for(j = 0; j < size; j++) {
		KeyNode *node = (KeyNode *)malloc(sizeof(KeyNode));     //Defines a pointer to a structure variable
		node->num = arr[j];    
		node->next = NULL;
		int index = ReturnCount (arr[j]);  //The mapping function calculates the bucket number
    printf ("array[%d] data %3d   Fangdi%2d Barrels\n", j, arr[j], index);
		KeyNode *p = bucket_num[index];   //Initialize P to become the head pointer of the data chain in the bucket
        //There is no data in this bucket
		if(p->num == 0) {
			bucket_num[index]->next = node;
			(bucket_num[index]->num)++;
		} else {
        //Insertion sorting of linked list structure
			  while(p->next != NULL && p->next->num <= node->num) {
				  p = p->next;
			  }	
			  node->next = p->next;
			  p->next = node;
			  (bucket_num[index]->num)++;
		}
	}
	//Print results
	KeyNode * k = NULL;  //Define an empty structure pointer to store the output result
  int arr_size = 0;
	for(i = 0; i < BUCKET_SIZE; i++) { //Assign back to the original array
    for(k = bucket_num[i]->next; k != NULL; k = k->next) {
      arr[arr_size++] = k->num;
    }			
  }		

}

test

void PrintArr (int arr[], int n) //Print array
{
  for (int i = 0; i < n; i++) {
    printf ("%d ",arr[i]);
  }
  printf ("\n\n");
}
 
int main()
{
	int arr[] = {66, 832, 1, 90, 7, 296, 3, 52};
	int size = sizeof(arr)/sizeof(arr[0]);    //Calculate array length
  
  printf ("Original data:\n");
  PrintArr (arr, size);

	bucket_sort(arr, size);

  printf ("\n New data:\n");
  PrintArr (arr, size);
  
  return 0;
}

10. Radix Sort

Cardinality sorting is sorting according to the low order, and then collecting; Then sort according to the high order, and then collect; And so on until the highest order. Sometimes some attributes are prioritized. They are sorted first by low priority and then by high priority. The final order is the high priority, the high priority, the same high priority, and the low priority, the high priority.

Algorithm implementation

  1. Get the maximum number in the array and get the number of bits;
  2. arr is the original array, and each bit is taken from the lowest bit to form a radius array;
  3. Count and sort the radix (using the characteristics that count sorting is suitable for a small range of numbers)
/* Get the index value of the input number, dec specifies the number of digits, 3 represents the number of hundreds, order specifies the index of which digit to get, 1 represents one digit, 2 represents ten digits, and 3 represents hundreds */
int get_index(int num, int dec, int order)
{
  int i, j, n;
  int index;
  int div;
 
  /* Based on the number of digits, the unneeded high-order digits are subtracted cyclically */
  for (i=dec; i>order; i--) {
    n = 1;
    for (j=0; j<dec-1; j++)
      n *= 10;
    
    div = num/n;
    num -= div * n;
    dec--;
  }
 
  /* Obtain the integer corresponding to the number of digits */
  n = 1;
  for (i = 0; i < order-1; i++)
    n *= 10;
 
  /* Get index */
  index = num / n;
 
  return index;
}
 
/* Perform cardinality sorting */
void radix_sort(int array[], int len, int dec, int order)
{
  int i, j;
  int index;     /* Sort index */
  int tmp[len];  /* Temporary array, which is used to save the intermediate results to be sorted */
  int num[10];   /* An array that holds index values */

  memset(num, 0, 10*sizeof(int));  /* Initial zeroing of array */
  memset(tmp, 0, len*sizeof(int)); /* Initial zeroing of array */
 
  if (dec < order) /* Return after the highest order sorting is completed */
    return;
 
  for (i = 0; i < len; i++) {
    index = get_index(array[i], dec, order);  /* Get index value */
    num[index]++;  /* Corresponding bit plus one */
  }
 
  for (i = 1; i < 10; i++)
    num[i] += num[i-1]; /* Adjust index array */
 
  for (i = len-1; i >= 0; i--) {
    index = get_index(array[i], dec, order);  /* Get the index of each number from the end of the array */
    j = --num[index];  /* Calculates the position of the number in the array after bitwise sorting according to the index */
    tmp[j] = array[i]; /* Put numbers into temporary array */
  }
 
  for (i = 0; i < len; i++)
    array[i] = tmp[i];  /* Copy from temporary array to original array */
 
  printf("the %d time\n", order);
  PrintArr (array, len);

  printf("\n");
 
  /* Continue sorting by the higher digit size */
  radix_sort(array, len, dec, order+1);
 
    return;
}

test

void PrintArr (int arr[], int n) //Print array
{
  for (int i = 0; i < n; i++) {
    printf ("%d ",arr[i]);
  }
  printf ("\n\n");
}

int main(int argc, char *argv[])
{
  int i;
  int array[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
 
  int len = sizeof (array) / sizeof (array[0]);  /* Number of test data */
  int dec = 2;   /* Maximum number of data bits, 2 represents 1 bit */
  int order = 1; /* The number of bits to be sorted. 1 represents one bit, 2 represents ten bits, and 3 represents hundreds */
 
  printf("Original data:\n");
  PrintArr (array, len);

  /* Sort function, starting with a bit */
  radix_sort(array, len, dec, order);
 
  printf("New data:\n");
  PrintArr (array, len);
 
  return 0;
}

Topics: Algorithm data structure