在这里仍然使用分冶法、、、分冶法的具体思想我就不多谈了、、可以参考我之前写的博文
在这里主要记录一下解决这道题是应该注意的细节问题、、
我们要分清这个次最大值包括最大值吗?
如 78,,79,79 应该输出79,79 还是 79,78呢?
在这里我默认为输出79,78.
主要代码如下:
#include <stdio.h>
#include <limits.h>
void search(int *a,int front,int end,int *max1,int *max2)
{
int left_max1,left_max2,right_max1,right_max2;
if(end-front<=1)
{
if(a[front]>a[end])
{
*max1=a[front];
*max2=a[end];
}
else
{
*max1=a[end];
*max2=a[front];
}
return;
}
search(a,front,(front+end)/2,&left_max1,&left_max2);
search(a,(front+end)/2+1,end,&right_max1,&right_max2);
if(left_max1==left_max2)
left_max2=INT_MIN;
if(right_max1==right_max2)
right_max2=INT_MIN;
if(left_max1>right_max1)
{
*max1=left_max1;
*max2=left_max2>right_max1?left_max2:right_max1;
}
else if(left_max1<right_max1)
{
*max1=right_max1;
*max2=left_max1>right_max2?left_max1:right_max2;
}
else
{
*max1=left_max1;
*max2=left_max2>right_max2?left_max2:right_max2;
}
}
思想和分冶法求数组最大值最小值思想是一样的、、、、但通过两部分分别求取得最大值次最大值求总体的最大值最小值方法变了、、
不再是第一部分的最大值和第二部分最大值比较、、第一步分次最大值和第二部分次最大值比较、、然后得到两部分所组成整体的最大值和次最大值
你仔细想想就可以明白了、、、因为第一部分的次最大值不一定就小于第二部分的最大值,有可能第一部分的次最大值大于第二部分的最大值。。
于是你可能写出如下代码:
void search(int *a,int front,int end,int *max1,int *max2)
{
int left_max1,left_max2,right_max1,right_max2;
if(end-front<=1)
{
if(a[front]>a[end])
{
*max1=a[front];
*max2=a[end];
}
else
{
*max1=a[end];
*max2=a[front];
}
return;
}
search(a,front,(front+end)/2,&left_max1,&left_max2);
search(a,(front+end)/2+1,end,&right_max1,&right_max2);
if(left_max1>right_max1)
{
*max1=left_max1;
*max2=left_max2>right_max1?left_max2:right_max1;
}
else {
*max1=right_max1;
*max2=left_max1>right_max2?left_max1:right_max2;
}
}
这样就对了吗?、、、
不一定吧、、、
如果求出的left_max1,right_max,1,left_max2,right_max2,符合
left_max1==right_max1 left_max1==left_max2>right_max1 、、、、 right_max1刚好是该数组的次最大值。
那么我们会得到*max1==left_max1;*max2==left_max1==left_max2;
也就是说如果该数组中出现了两个最大值、、、可能会得到结果为最大值和次最大值结果都为最大值、、、
如:
于是在这里我引入了头文件#include <limit.h>
当最大值和次最大值一样大时,将次最大值赋值为INT_MIN、、、
实现如下:
if(left_max1==left_max2)
left_max2=INT_MIN;
if(right_max1==right_max2)
right_max2=INT_MIN;
if(left_max1>right_max1)
{
*max1=left_max1;
*max2=left_max2>right_max1?left_max2:right_max1;
}
else {
*max1=right_max1;
*max2=left_max1>right_max2?left_max1:right_max2;
}
这样还不够:
如果求出的left_max1,right_max,1,left_max2,right_max2,符合
left_max1==right_max1 left_max1==right_max1, right_max2刚好是该数组的次最大值,
按照上面的代码、、、、、你会得到*max1=right_max1,*min=left_max1,
、、、、、所起这一部分应该注意。