在一维整型数组中找出比数组元素最大值小的次大元素的下标,有一个符合条件元素则输出一个下标,有多个符合条件元素则输出多个下标。其中,寻找次大元素下标的函数原型为:int findSecondMax(int *p, const int len);
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int a[8]={1,3,8,2,9,5,4,8}; //定义数组
int i;//定义变量
int findSecondMax(int *p, const int len); //函数声明语句
printf("一维数组中的元素是:");
for( i=0 ; i<8 ; i++)
{
printf("%d ",a[i]);
}
printf("\n");
findSecondMax(a, 8); //调用函数
printf("\n");
system("pause");
return 0;
}
int findSecondMax(int *p, const int len) //函数的定义
{
int i,max,semax,count=0; //定义最大值和最小值变量
max=semax=p[0];
for(i=0;i<len;i++) //通过循环找最大值
{
if(max<p[i])
{
max=p[i];
}
}
for(i=0;i<len;i++) //找出次大值
{
if((semax<p[i])&&(p[i]<max))
{
semax=p[i];
}
}
printf("次大元素(%d)的下标是:",semax);
for(i=0;i<len;i++) //利用循环找出次大元素下标
{
if(semax==p[i])
{
if(count!=0)
printf(",%d",i); //如果不是第一个次大元素,前面输出一个逗号
else
printf("%d",i); //如果是第一个次大元素,原样输出
count++;
}
}
}
用分治法,先求出左边的最大值leftmax和次大值leftsecond,再求出右边的最大值rightmax和次大值rightsecond,然后合并,如何合并呢?分情况考虑
1 如果leftmax > rightmax,那么可以肯定leftmax是最大值,但次大值不一定是rightmax,但肯定不是rightsecond,只需将leftsecond与rightmax做一次比较即可。
2 如果rightmax > leftmax,那么可以肯定rightmax是最大值,但次大值不一定是leftmax,但肯定不是leftsecond,所以只需将leftmax与rightsecond做一次比较即可。
[html] view
plaincopy
- // 找出数组的最大值和次大值,a是待查找的数组,left和right是查找区间,max和second存放结果
- void MaxandSec(int a[], int left, int right, int&max, int&second)
- {
- if(left == right)
- {
- max = a[left] ;
- second = INT_MIN;
- }
- else if(left +1== right)
- {
- max = a[left] > a[right] ? a[left] : a[right] ;
- second = a[left] < a[right] ? a[left] : a[right] ;
- }
- else
- {
- int mid =(right + left) /2 ;
- int leftmax ;
- int leftsecond ;
- MaxandSec(a, left, mid, leftmax, leftsecond) ;
- int rightmax ;
- int rightsecond ;
- MaxandSec(a, mid +1, right, rightmax, rightsecond) ;
- if (leftmax > rightmax)
- {
- max = leftmax ;
- second = leftsecond > rightmax ? leftsecond : rightmax ;
- }
- else
- {
- max = rightmax ;
- second = leftmax < rightsecond ? rightsecond : leftmax ;
- }
- }
- }