A seek array [] and the second largest maximum value in the interval [lo, hi) of.
Returns the index of the maximum index and the second largest value x1 x2
Iteration 1:
(1 iterative codes are bug, if A [lo] as the maximum value, the result x1, x2 are LO)
void max2(int A[], int lo, int hi, int &x1, int &x2)
{
for(x1=lo, int i=lo+1; i<hi; i++)
if( A[i] > A[x1])
x1=i;
for(x2=lo, int i=lo+1; i<x1; i++)
if( A[i] > A[x2])
x2=i;
for(int i=x1+1; i<hi; i++)
if( A[i] > A[x2])
x2=i;
}
Iteration 2:
(1 iterations will not improve the relative complexity of the worst-case time)
void swap(int &x, int &y)
{ int t=x; x=y; y=t;}
void max2(int A[], int lo, int hi, int &x1, int &x2)
{
if(A[x1=lo] < A[x2=lo+1]) //把x1设为最大值下标,x2设为次大值下标
swap(x1,x2);
for(int i=lo+2; i<hi; i++)
if(A[i]>A[x2]) //先与A[x2]比较
if(A[x2=i]>A[x1]) //若比A[x2]大,再把令x2指向i,然后A[x2]与A[x1]比较
swap(x1,x2); //若比A[x1]也大,则交换x1,x2, 保持x1为最大,x2为次大
}
Recursion:
(divide and conquer)
(the array into left and right two arrays, each seeking about two times the maximum value and a large value of the array, then selecting the maximum value and the second largest value from the result)
void swap(int &x, int &y)
{
int t = x; x = y; y = t;
}
void max2(int A[], int lo, int hi, int &x1, int &x2)
{
if (lo + 2 == hi)//区间内只剩2个元素,为递归基之一
{
if (A[x1 = lo] < A[x2 = lo + 1])
swap(x1, x2);
return;
}
if (lo + 3 == hi)//区间只剩3个元素,为递归基之一
{
if (A[x1 = lo] < A[x2 = lo + 1])
swap(x1, x2);
if (A[lo + 2] > A[x2])
if (A[x2 = lo + 2] > A[x1])
swap(x1, x2);
return;
}
//分而治之
int mi = (lo + hi) / 2;
int x1l, x2l, x1r, x2r;
max2(A, lo, mi, x1l, x2l);
max2(A, mi, hi, x1r, x2r);
if (A[x1l]>A[x1r])
{
x1 = x1l;
x2 = A[x1r]>A[x2l] ? x1r : x2l;
}
else
{
x1 = x1r;
x2 = A[x2r]>A[x1l] ? x2r : x1l;
}
}
Test code:
#include <stdio.h>
void max2(int A[], int lo, int hi, int &x1, int &x2);
int main()
{
int arr[100];
int n;
while (scanf("%d", &n) == 1)
{
for (int i = 0; i < n; i++)
scanf("%d", arr + i);
printf("\n数组是:\n");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
int x1, x2;
max2(arr, 0, n, x1, x2);
printf("\n最大值:%d 次大值:%d\n", arr[x1], arr[x2]);
}
return 0;
}
ps: mi Why can this calculation mi = (LO + hi) / 2
(although this problem is very simple, but I had tangled for a long time, they still write it down.)
The most intuitive algorithm mi = lo + (hi-lo ) / 2
simplifying
mi The = LO + (Hi-LO) / 2
= LO + Hi / 2 - LO / 2
= (2 * LO) / 2 + Hi / 2 - LO / 2
= (2 * LO + Hi - LO ) / 2
= (LO + Hi) / 2
may be intuitively understood by the following image