This chapter median and sequence statistics is short and the last chapter in the second part of this book.
Write some code.
Returns the minimum value of an array.
Java code
Int minimum (INT [] ){
Int min = A [0];
For (INT I = 1; I <A. length; I ++ ){
If (min> A [I]) {
Min = A [I];
}
}
Return min;
}
You do not need to write a test. This method requires n-1 comparisons.
At the same time, find the maximum and minimum values.
If the above method is used, the problem can be solved after 2 (n-1) times. Of course it can be less.
Java code
Int [] minandmax (INT [] ){
Int I = 1;
Int min = A [0];
Int max = A [0];
If (A. Length & 1) = 0) {// even
I = 2;
Max = A [1];
}
If (min> MAX ){
// Swap
Int T = min;
Min = max;
Max = T;
}
// The following process starts from I and ends until it ends. There are a total of even numbers.
For (; I <A. length; I + = 2 ){
Int M = A [I];
Int n = A [I + 1];
If (M> N ){
// Swap
Int T = m;
M = N;
N = T;
}
// Now M <= N
If (min> m ){
Min = m;
}
If (max <n ){
Max = N;
}
}
Int [] B = {min, max };
Return B;
}
Now, three comparisons are performed for each loop. A total of three (n-1)/Two) comparisons are performed, plus a comparison before the loop. A total of three (n/2) comparisons are performed.
Select the number smaller than I
We can sort it once and then output the number smaller than I, but the complexity will be the same as the sorting.
There are better methods:
Java code
Int randselect (INT [] ary, int left, int right, int index) {// find the number of small indexes from [left, right]
If (left> right | index> right-left ){
Throw new illegalargumentexception ();
}
If (Left = right ){
Return ary [left]; // Index = 0
}
Int mid = partition (ary, left, right); // divide the array once. [left, mid-1] [Mid] [Mid + 1, right]
Int Len = mid-left;
If (Index = Len) {// exactly
Return ary [Mid];
} Else if (index <Len) {// the number to be searched is in the left Interval
Return randselect (ary, left, mid-1, index );
} Else {// the number to be searched is in the right range. Of course, you need to find a small number in index-len-1, because you need to deduct the left range and mid
Return randselect (ary, Mid + 1, right, index-len-1 );
}
}
In this example, partition encountered in quick sorting.
Java code
Int partition (INT [] A, int low, int high ){
Int x = A [low];
Int M = low;
For (INT I = low + 1; I <= high; I ++ ){
If (A [I] <X ){
Swap (A, ++ m, I );
}
}
Swap (A, low, M );
Return m;
}
Void swap (INT [] A, int I, Int J ){
Int T = A [I];
A [I] = A [J];
A [J] = T;
}
Not busy. Write a test first.
Java code
@ Test
Public void testrandselect (){
Random Rand = new random ();
For (INT I = 0; I <100; I ++ ){
Int [] A = genrandary (I + 1 );
Int [] B = arrays. copyof (A, A. Length); // because randselect sorts array A, copy it first
Int K = Rand. nextint (A. Length); // We need to select the K-small number from.
Int M = randselect (A, 0, A. Length-1, k );
Arrays. Sort (B); // sort B again
Assertequals (B [K], M); // at this time, m should be the same as B [k]
}
}
We can see that the operation is successful :)
The complexity is analyzed as follows.
First, reconstruct randselect and change it to the number of comparisons.
Java code
Int randselect2 (INT [] ary, int left, int right, int index ){
If (left> right | index> right-left ){
Throw new illegalargumentexception ();
}
If (Left = right ){
Return 0; // modified
// Return ary [left];
}
Int times = right-left; // The following partition must be compared right-left times. For details, see quick sorting (note 4)
Int mid = partition (ary, left, right );
Int Len = mid-left;
If (Index = Len ){
Return times;
// Return ary [Mid];
} Else if (index <Len ){
Return times + randselect (ary, left, mid-1, index); // modified
} Else {
Return times + randselect (ary, Mid + 1, right, index-len-1); // modified
}
}
Then the method above is simplified.
1. parameter check is not required
2. Left = right test ---> N = 0
3. Represent left and right as N-related, and remove a and index.
3. In general, the partition is evenly distributed, and we assume that all code paths go through the branch of index <Len
The above method can be simplified to the average comparison times.
Java code
Int randselect2 (int n ){
If (n = 0 ){
Return 0;
}
Int times = n-1; // Number of partition comparisons
Return times + randselect2 (n/2); // halved after each split
}
The recursive formula is T (n) = T (n/2) + (n-1)
The above written series is: (n-1) + (n-1)/2 + (n-1)/4 + (n-1)/8 +...
(N-1) (1 + 1/2 + 1/4 + 1/8 +...) ---> almost 2 (n-1)
Therefore, the complexity of the randselect algorithm is linear.