Sequence statistics (Selection Problem)

Definition

In a set composed of n elements, the I-th sequence statistic is the I-th small element in the set. For example, in a element set, the minimum value is the first sequence statistic (I = 1), and the maximum value is the nth sequence statistic (I = N ).

Find minimum

In a set with n elements, how many comparisons are required to determine the minimum element? A simple idea is to traverse each element in the Set in sequence and record the currently smallest element. In the following sorting, assume that the element of the set is stored in array A, and. length = n.

Minimum ()

Min = A [1]

For I = 2 to A. Length

If Min <A [I]

Min = A [I]

Return min

Of course, the maximum value can also be obtained through n-1 comparisons.

At the same time, find the maximum and minimum values

The simplest method is to find the maximum and minimum values independently, which requires n-1 comparisons and 2n-2 comparisons. In fact, you only need to compare a maximum of 3 * floor (n/2) (the floor () function is rounded down) to find the maximum and minimum values at the same time. The specific method is to record the known maximum and minimum values, but not compare each input element with the current minimum and maximum values. The cost of doing so is that each element needs to be compared twice, instead, the input elements are processed in pairs. First, a pair of input elements are compared with each other, and then the smaller elements are compared with the current minimum values, compare the large value with the current maximum value. In this way, the two elements need to be compared three times in total.

How to set the known maximum and minimum values depends on whether N is an odd or even number. If n is an odd number, the initial values of the minimum and maximum values are set to the values of the first element, then the remaining elements are processed in pairs. If n is an even number, compare the first two elements to determine the initial values of the minimum and maximum values, and then process the remaining elements in pairs like n is an odd number.

If n is an odd number, then a total of 3*(n-1)/2 Comparison, if n is an even number, first an initial comparison, then 3 (n-2) /2 comparisons: A total of 3n/2-2 comparisons are performed. Therefore, in either case, the total number of comparisons is at most 3 * floor (n/2.

Linear Time Selection Algorithm

Generally, the problem of selection seems more difficult than finding the minimum value. However, the two problems have the same running time: θ (n ). The following is a sort algorithm that solves the selection problem. Like the Quick Sort Algorithm, input arrays are divided recursively. However, unlike the Quick Sort Algorithm, quick sorting recursively processes both sides of the Division, while randomized_select only processes one side of the Division. The expected run time of quick sorting is θ (nlgn ), the expected running time of randomized_select is θ (N). Here, we assume that the input data is different from each other.

Pseudocode

// I is the maximum value to be selected, and K is the maximum value of the principal element After partitioning.

Randomized_select (A, P, R, I)

If P = r

Return a [p]

Q = randomized_partition (A, P, R );

K = Q-p + 1

If K = I

Return a [Q]

Else if I <K

Return randominze_select (A, P, Q-1, I)

Else

Return randomized_select (A, q + 1, R, I-K)

Performance Analysis

The worst run time of randomized_select is θ (N2). This is true even if you are looking for the smallest element, because during each division, it may be very far away and always divided by the largest of the remaining elements, however, the Division operation takes θ (n) time, but the algorithm is randomly divided, so there is no specific input data that will lead to the worst case.

The expected running time of the algorithm is θ (N). For details, refer to "Introduction to algorithms" p121.

C language code implementation

# Include <stdio. h> # include <stdlib. h> # include <time. h> void randomized_select (int * array, int begin, int end, int position); int randomized_partion (int * array, int begin, int end); int partion (int * array, int begin, int end); void swap (int * array, int P, int Q); void quicksort (int * array, int begin, int end); main () {int array [] = {, 64}; int I, K; printf ("array before sorting: \ n "); for (I = 0; I <13; I ++) printf ("% d \ t", array [I]); putchar ('\ n '); putchar ('\ n'); quicksort (array, 0, 11); printf ("sorted array: \ n"); for (I = 0; I <13; I ++) printf ("% d \ t", array [I]); For (k = 1; k <= 13; k ++) {putchar ('\ n'); printf ("\ n is sorted in ascending order, with the number of % d digits:", k); randomized_select (array, 0, 12, k);} putchar ('\ n');} void swap (int * array, int P, int q) {int temp; temp = array [p]; array [p] = array [Q]; array [Q] = temp;} int randomized_partion (int * array, int begin, int end) {// temp is a random number, int piviot_position, temp; srand (unsigned INT) Time (null). // The srand function initializes the random number generator with the parameter value, here we use the current time of the day as the seed of the random number generator temp = rand () % (end-begin); piviot_position = temp + begin; swap (array, begin, piviot_position ); return partion (array, begin, end);} int partion (int * array, int begin, int end) {// select the first element as the principal element int piviot; int last, PTR; piviot = array [begin]; for (last = begin, PTR = begin + 1; PTR <= end; PTR ++) {If (array [PTR] <= piviot) {swap (array, ++ last, PTR) ;}} swap (array, last, begin); return last ;} void randomized_select (int * array, int begin, int end, int position) {// The value of number is the position of the principal component in the sorted array int piviot_position; int number; if (begin = END) {printf ("% d \ n", array [begin]); return;} piviot_position = randomized_partion (array, begin, end ); number = piviot_position-begin + 1; if (number = position) printf ("% d \ n", array [piviot_position]); else if (position <number) randomized_select (array, begin, piviot_position-1, position); else randomized_select (array, piviot_position + 1, end, position-number);} void quicksort (int * array, int begin, int end) {int medium; If (begin <End) {medium = partion (array, begin, end); quicksort (array, begin, medium-1); quicksort (array, medium + 1, end );}}