代码
原始版本(写的有点繁琐)
//分而治之 2n-3
#include<stdio.h>
void MAX(int A[],int lo,int hi,int *x1,int *x2)
{
int max1,max2,f;
for(int i=lo;i<hi;i++)
if(A[i]<A[i+1])
{*x1=A[i+1];
f=i;}
for(int i=lo;i<f;i++)
if(A[i]<A[i+1])
*x2=A[i+1];
for(int i=f+1;i<hi;i++)
if(A[i]>*x2)
*x2=A[i];
}
int main()
{
int a[10],i,j;
printf("输入数组;");
for(int i=0;i<10;i++)
scanf("%d",&a[i]);
printf("输入区间,从零开始:");
scanf("%d %d",&i,&j);
int x1=0,x2=0;
MAX(a,i,j,&x1,&x2);
printf("%d %d",x1,x2);
return 0;
}
优化
//递归 最好n-1 最坏2n-3
#include<stdio.h>
void swap(int *x,int *y)
{
int temp;
if(*x<*y)
{temp=*x;
*x=*y;
*y=temp;}
}
void MAX(int A[],int lo,int hi,int *x1,int *x2)
{
*x1=A[lo];
*x2=A[lo+1];
if(*x1<*x2)
swap(&*x1,&*x2);
for(int i=lo+2;i<=hi;i++)
if(A[i]>*x2)
{*x2=A[i];
if(*x2>*x1)
swap(&*x1,&*x2);}
//下面的代码错误,因为如果是递增数列,if(A[i]>*x1)一直执行而*x2=A[i];不会执行
/*for(int i=lo+2;i<=hi;i++)
if(A[i]>*x2)
if(A[i]>*x1)
*x1=A[i];
else
*x2=A[i];*/
}
int main()
{
int a[10],i,j;
printf("输入数组;");
for(int i=0;i<10;i++)
scanf("%d",&a[i]);
printf("输入区间,从零开始:");
scanf("%d %d",&i,&j);
int x1=0,x2=0;
MAX(a,i,j,&x1,&x2);
printf("%d %d",x1,x2);
return 0;
}
二次优化(伪代码)
(写不动了,效率高,但太多不想写)
原理:先分两边,两边在不断递归二分,求出两边第一二大,原始两边最大比较,大的即是最大max1,另一个max2,在最大那边第二大与max2比较,大的是max2
//递归+分治 5n/3-2
//伪代码 求的是两个数的位置,x1,x2
//先分两边,两边在不断递归二分,求出两边第一二大,原始两边最大比较,大的即是最大max1,另一个max2,在最大那边第二大与max2比较,大的是max2
void MAX(int A[],int lo,int hi,int &x1,int &x2)
{
if(lo+2==hi)
{
........;
return..;
}
if(lo+3==hi)
{
........;
return..;
}
int mi=(lo+hi)/2;
int x1L,x2L;
MAX(A,lo,mi,x1L,x2L);
int x1R,x2R;
MAX(A,mi,hi,x1R,x2R);
if(A[x1L]>A[x1R])
{
x1=x1L;
x2=(A[x2L]>A[x1R])?x2L:x1R;
}
else
{
x1=x1R;
x2=(A[x1R]>A[x2R])?x1L:x2R;
}
}