Three linear time O (n) sorting algorithms-count-base-bucket-C ++ implementation

Source: Internet
Author: User

Introduction


Note: Because no public editor is enabled, it is convenient: when the following time complexity representation is involved, its accesskey is replaced by the following symbol:

First, let's look atTheorem: In the worst case, a comparison of $ (nlgn) times is required for any comparative sorting algorithm. It can be proved by the decision tree model. For details, see section 8th of Introduction to algorithms.

This Theorem points out the lower bound of the time complexity of comparative sorting, that is, there is no less.

The three algorithms described below are not comparison-based sorting algorithms. They all make certain assumptions about the input data, that is, they take advantage of the characteristics of specific data.

I. Counting sorting


1. Problem Description:HypothesisEach of the n elements in the array is an integer between 0 and k. K is a positive integer.

2. Basic Ideas: For each input element x, the range size is [0, k] to determine the number of elements smaller than x in the array. Since x is a positive integer, you can directly place x in its position in the final output array.

3. Algorithm Description:

Input: A [1... n], input array; C [0... k], provide temporary storage area, initial value: 0 --- O (k)

Output: B [1... n], storing the sorting result

(1) obtain the input array A [1... in n], the value is equal to the number of elements in A [j] and is stored in the corresponding C [1... k]: C [A [I] = C [A [I] + 1 --- O (n)

(2) obtain the input array A [1... in n], the value is less than or equal to the number of elements in A [j], and is stored iteratively in the corresponding C [1... in k]: C [j] = C [J-1] + C [j] --- O (K)

(3) After the first two steps, the value in C [I] indicates the number of elements smaller than or equal to I, that is, the value of I in A [1... n] and store it in B [1... n] medium: B [C [A [j] = A [j], C [A [j] = C [A [j]-1 (there may be equal elements in the array) --- O (n)

4. Time Complexity: O (k) + O (n) + O (k) + O (n), the total running time is: @ (k + n). In practice, when k = O (n), the running time is:@ (N).

5. Algorithm Implementation:

#include <stdio.h>const int K = 5;const int N = 6;int input[N+1] = {-1, 2, 3, 4, 2 ,1, 5};int output[N+1];int count[K]={0};void print(int array[], int n){for(int i = 1; i <=n; i++){printf("%d ", array[i]);}printf("\n");}void countSort(int input[], int output[], int n){int i;for(i = 1; i <= n; i++){//equal to input[i]count[input[i]] = count[input[i]] +1;}for(i = 1; i <= K; i++){//less ro equal to icount[i] = count[i-1] + count[i];}for(i = n; i >= 1; i--) //form large to small to make sorting stable{output[count[input[i]]] = input[i];count[input[i]]--;}}int main()  {countSort(input, output, N);print(output, N);    return 0;  }  

Ii. Base sorting

1. Problem DescriptionGiven n d-digits, each digit may have k values and is sorted. For example, four three-digit numbers: 123,367,124,756, n = 4, d = 3, and K value is 10.

2. Basic Ideas: First, sort by the lowest valid digit to collect the results. Then, sort by the next low valid digit to collect the results, and so on. repeat this process, until all the d-digit numbers are sorted.

Check itemsExample(Example from introduction to algorithms 8.3, P100 ):

Note:: The sorting of each bit must be a stable sorting; otherwise, the sorting may be incorrect. For example, when sorting the highest bits, the first 436 is in front of the first 457. Because the highest bits are 4, the highest bits of the two numbers in this sorting are equal. If it is not a stable sorting, the result 457 may be prefixed with 436, so the result is incorrect. Stable sorting ensures that 436 is still in front of 457 after completion.

3. Algorithm Description:

Input array: A [1... n]

RADIX-SORT (A, d)

For I <-1 to d

Do use a stable sort to sort array A on digit I // You can select count sorting.

4. Time Complexity: It can be seen from the count sorting in the middle that the sorting time for each bit is: @ (k + n). A total of d times are executed here, so the time complexity is as follows: @ (d * (k + n). When d is a constant and k = O (n), the base sorting has a linear running time:@ (N). For more general and specific analysis, you can participate in the introduction to Algorithms8.3 and 8.4P101, which has detailed analysis: how to break down each keyword into several BITs, and in those cases, the time complexity is the best. Here we will only introduce some conclusions and implementation methods.

5. Algorithm Implementation:

#include <stdio.h>#include <math.h>const int N = 7;const int D = 3;const int K = 10;int count[K] = {0};//int input[N+1] = {-1, 329, 457, 657, 839, 436, 720, 355};int output[D+1][N+1]={{-1, 329, 457, 657, 839, 436, 720, 355}};void print(int array[], int n){for(int i = 1; i <=n; i++){printf("%d ", array[i]);}printf("\n");}int getDigit(int number, int d){if(d > D)return -1;return number%(int)pow(10,d) / (int)pow(10,d-1); }void countSort(int input[], int output[], int n, int d){int i;int digit;for(i = 1; i <= n; i++){digit = getDigit(input[i],d);count[digit] = count[digit] +1;}for(i = 1; i <= K; i++){count[i] = count[i-1] + count[i];}for(i = n; i >= 1; i--) //form large to small to make sorting stable{digit = getDigit(input[i],d);output[count[digit]] = input[i];count[digit]--;}}void initDataStruct(int count[]){for(int i= 0; i < K; i++){count[i] = 0;}}void radixSort(int output[][N+1], int n, int d){for(int i = 1; i <= d; i++){countSort(output[i-1], output[i], n, i);initDataStruct(count);}}int main()  {radixSort(output, N, D);print(output[D], N);        return 0;  }

Iii. Sort buckets

1. Problem Description:HypothesisAn input array is generated in a random process. In this process, elements are evenly distributed in the range [0, 1) to sort the input array.

2. Basic Ideas: Similar to the zipper method used to resolve hash conflicts in a hash list, a bucket is essentially a linked list. elements with the same keywords are placed in the same bucket. Since the elements in the input array are evenly and evenly distributed independently on [0, 1), many elements are generally not allocated to the same bucket. After the hash is complete, sort the elements in each bucket first, and then collect the elements in each bucket in order to obtain an ordered array.

3. Algorithm Description:

Input: A [1... n]; B [0... n-1]: Secondary array linked list, used for hashed Elements

Output: sorted A [1... n]

(1) divide the interval [0, 1) into n subintervals of the same size, or buckets (which can be achieved through the auxiliary array linked list B [0... N-1 ).

(2) It is known that the hash function is f (x) = floor (n * x) and rounded down, then the array element A [I] is allocated to the bucket (linked list) B [floor (n * A [I])] --- @ (n)

(3) sort the elements in each bucket B [I] (which can be inserted for sorting) --- n * O (2-1/n)

(4) Collect results from buckets in order.

4. Time Complexity: According to the algorithm description in step 3, except step (3), the time for other parts in the worst case is O (n ). The knowledge of mathematical statistics can be obtained. In step (3), each bucket is sorted. The expected running time is 2-1/n. For details, see: in Section 8.4 of Introduction to algorithms, P103), the total time in step (3) is n * (2-1/n). Therefore, the expected running time of Bucket sorting is as follows: @ (n) + n * (2-1/n) =@ (N)

5. Algorithm Implementation:

#include <stdio.h>#include <math.h>const int N =10;double input[N+1] = {-1, 0.78, 0.17, 0.39, 0.26, 0.72, 0.94, 0.21, 0.12, 0.23, 0.68};typedef struct BucketNode{double data;struct BucketNode* next;}* bucketList, bucketNode;bucketList bucketArr[N];void print(bucketList bucketArr[]){for(int i = 0; i < N; i++){bucketNode* pb = bucketArr[i];while(pb){printf("%e ", pb->data);pb = pb->next;}printf("\n");}printf("\n");}void initBucketList(bucketList bucketArr[]){for(int i = 0; i < N; i++){bucketArr[i] = NULL;}}bool insertBucketWithSorting(bucketList& bucket, double data){//sorting while insertingbucketNode* pb = new bucketNode;if(NULL == pb)return false;pb->data = data;if(NULL == bucket || pb->data < bucket->data){//insert before the first elementpb->next = bucket;bucket = pb;return true;}bucketNode* ptemp = bucket;bucketNode* ptempn = bucket->next;while(ptempn){//insert after the first element(that is in the middle)if(pb->data < ptempn->data){pb->next = ptempn;ptemp->next = pb;break;}ptemp = ptempn;ptempn = ptempn->next;}if(NULL == ptempn){//insert after the last elementptemp->next = pb;pb->next = NULL;}return true;}void destroyBucketList(bucketList bucketArr[]){for(int i = 0; i < N; i++){while(bucketArr[i]!= NULL){bucketNode* pb = bucketArr[i];bucketArr[i] = bucketArr[i]->next ;delete pb;pb = NULL;}}}void bucketSort(double input[], bucketList bucketArr[],int n){for(int i = 1; i <= n; i++){int index = (int)floor(input[i]*n);insertBucketWithSorting(bucketArr[index], input[i]);}  }int main()  {initBucketList(bucketArr);bucketSort(input, bucketArr, N);print(bucketArr);destroyBucketList(bucketArr);    return 0;  }  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.