Top ten sorting (quick sort, count sort, bucket sort, cardinal sort)

1, Quick sort

Through one-time sorting, the data to be sorted is divided into two independent parts. All data in one part is smaller than all data in the other part, and then the two parts of data are sorted quickly according to this method. The whole sorting process can be recursive, so that the whole data becomes an ordered sequence.

Algorithm implementation

  1. Select a number in the array and scan the array from both ends of the array,

  2. Starting from the second half, if an element is found to be smaller than the value of the reference point, the position is exchanged

  3. Then start scanning from the front half, find that there are elements greater than the value of the reference point, and continue to exchange positions

  4. In this cycle, the left side of this point is smaller than him and the right side is larger than him

After that, the first half and the second half are sorted recursively. When the current half and the second half are ordered, the array will be naturally ordered.

Complexity

 

Code example

void QSort(SqList *L, int low, int high)
{
    int pivot;
    if(low < high)
    {
        pivot = Partition(L, low, high);
        QSort(L, low,, pivot - 1);
        QSort(L, pivot + 1, high);
    }
}

int Partition(SqList *L, int low, int high)
{
    int pivotkey;
    pivotkey = L->r[low];
    while(low < high)
    {
        while(low < high && L->r[high] >= pivotkey)
            high--;
        swap(L, low, high);
        while(low < high && L->r[low] <= pivotkey)
            low++;
        swap(L, low, high);
    }
    return low;
}

Graphic process

  2, Count sort

Count sorting is to convert the input data values into keys and store them in an additional array space. The counting sorting algorithm is not based on element comparison, but uses array subscripts to determine the correct position of elements.

Algorithm implementation

1. Find the largest and smallest elements in the array to be sorted

2. Count the number of occurrences of each element with value i in the array and store it in item i of array C

3. Accumulate all counts (starting from the first element in C and adding each item to the previous item)

4. Reverse fill the target array: put each element i in item C(i) of the new array, and subtract 1 from C(i) for each element

Complexity

 

  Code example

void CountSort(int *arr, int len){
    if(arr == NULL) return;
    int max = arr[0], min = arr[0];
    for(int i = 1; i < len; i++){
        if(arr[i] > max)    max = arr[i];
        if(arr[i] < min)    min = arr[i];
    }
    int size = max - min + 1;
    int *count =(int*)malloc(sizeof(int)*size);
    memset(count, 0, sizeof(int)*size);

    for(int i = 0; i < len; i++)
        count[arr[i] - min]++;//Including yourself!
    for(int i = 1; i < size; i++)
        count[i] += count[i - 1];

    int* psort =(int*)malloc(sizeof(int)*len);
    memset(psort, 0, sizeof(int)*len);

    for(int i = len - 1; i >= 0; i--){
        psort[count[arr[i] - min]] = arr[i];
        count[arr[i] - min]--;
    }

    for(int i = 0; i < len; i++){
        arr[i] = psort[i];
    }

    free(count);
    free(psort);
    count = NULL;
    psort = NULL;
}

  3, Bucket sorting

The principle of bucket sorting is to divide multiple intervals with the same range. Each sub interval is self sorted and finally merged. It is an extended version of counting sorting. Counting sorting can be regarded as that each bucket only stores the same elements, while bucket sorting each bucket stores a certain range of elements. Through the mapping function, map the elements in the array to be sorted to each corresponding bucket, sort the elements in each bucket, and finally put the elements in the non empty bucket into the original sequence one by one.

Algorithm implementation

  1. Determine the number of buckets applied according to the difference range and mapping rules of the maximum element and the minimum element in the set to be sorted;

  2. Traverse the set to be sorted and move each element to the corresponding bucket;

  3. The elements in each bucket are sorted and moved to the sorted collection.

Complexity

The spatial complexity is O(N+M) and the time complexity is O(nlog(n / m)). When the number of buckets m is close to the number of data n, the time complexity is close to O(n)

Code example

/*     a -- Array to be sorted
 *     n -- Length of array a
 *     max -- Range of maximum values in array a*/
void bucketSort(int a[], int n, int max)
{
    int i,j;
    int buckets[max];

    // Initialize all data in buckets to 0.
    memset(buckets, 0, max*sizeof(int));

    // 1. Counting
    for(i = 0; i < n; i++) 
        buckets[a[i]]++; 

    // 2. Sorting
    for (i = 0, j = 0; i < max; i++) 
    {
        while( (buckets[i]--) >0 )
            a[j++] = i;
    }
}

Advanced Edition

#include<iterator>
#include<iostream>
#include<vector>
using namespace std;
const int BUCKET_NUM = 10;

struct ListNode{
    explicit ListNode(int i=0):mData(i),mNext(NULL){}
    ListNode* mNext;
    int mData;
};

ListNode* insert(ListNode* head,int val){
    ListNode dummyNode;
    ListNode *newNode = new ListNode(val);
    ListNode *pre,*curr;
    dummyNode.mNext = head;
    pre = &dummyNode;
    curr = head;
    while(NULL!=curr && curr->mData<=val){
            pre = curr;
            curr = curr->mNext;
    }
    newNode->mNext = curr;
    pre->mNext = newNode;
    return dummyNode.mNext;
}


ListNode* Merge(ListNode *head1,ListNode *head2){
    ListNode dummyNode;
    ListNode *dummy = &dummyNode;
    while(NULL!=head1 && NULL!=head2){
            if(head1->mData <= head2->mData){
                    dummy->mNext = head1;
                    head1 = head1->mNext;
            }else{
                    dummy->mNext = head2;
                    head2 = head2->mNext;
            }
            dummy = dummy->mNext;
    }
    if(NULL!=head1) dummy->mNext = head1;
    if(NULL!=head2) dummy->mNext = head2;//These two lines seem to be changed to while?

    return dummyNode.mNext;
}

void BucketSort(int n,int arr[]){
    vector<ListNode*> buckets(BUCKET_NUM,(ListNode*)(0));
    for(int i=0;i<n;++i){
            int index = arr[i]/BUCKET_NUM;
            ListNode *head = buckets.at(index);
            buckets.at(index) = insert(head,arr[i]);
    }
    ListNode *head = buckets.at(0);
    for(int i=1;i<BUCKET_NUM;++i){
            head = Merge(head,buckets.at(i));
    }
    for(int i=0;i<n;++i){
            arr[i] = head->mData;
            head = head->mNext;
    }
}

Graphic process

4, Cardinality sort

The principle is to cut the integer into different numbers according to the number of digits, and then compare them according to each number of digits.

Algorithm implementation

The cardinality of the single digit of any Arabic number is represented by 0 ~ 9. Therefore, 0 ~ 9 can be regarded as 10 barrels.

  1. It is classified according to the number of each digit of the sequence and divided into the specified bucket.

  2. After classification, take these numbers from each bucket in the order from No. 0 to No. 9.

  3. The resulting sequence is a sequence with an increasing trend in single digits.

  4. Next, the tens and hundreds of digits are sorted according to this method, and finally the sorted sequence can be obtained.

Complexity

  Code example

#include <stdio.h>
#include <string.h>
 
/* 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);
    for (i=0; i<30; i++)
        printf("%d  ", array[i]);
    printf("\n");
 
    radix_sort(array, len, dec, order+1);/* Continue sorting by the higher digit size */
 
    return;
}
 
int main(int argc, char *argv[])
{
    int i;
    int array[30] = {258, 976, 515, 337, 359, 701, 916, 494, 303, 175,
                        677, 825, 131, 560, 147, 254, 759, 814, 917, 382,
                        452, 114, 873, 585, 881, 127, 819, 658, 461, 435};
 
    int len = 30;  /* Number of test data */
    int dec = 3;   /* Data bits, 3 represents 3 bits */
    int order = 1; /* The number of bits to be sorted. 1 represents one bit, 2 represents ten bits, and 3 represents hundreds */
 
    printf("before\n");
    for (i=0; i<30; i++)
        printf("%d  ", array[i]);
    printf("\n");
 
    /* Sort function, starting with a bit */
    radix_sort(array, len, dec, order);
 
    printf("final\n");
    for (i=0; i<30; i++)
        printf("%d  ", array[i]);
    printf("\n");
 
    return 0;
}

Tags: C Algorithm data structure Permutation

Posted on Sun, 05 Sep 2021 01:34:03 -0400 by HuggyBear