一种思路是利用两次冒泡法,因为第一次冒泡,最大的在a[n-1],第二次冒泡后,次最大值在a[n-2]这样直接返回即可。核心代码如下:
for(int i=0; i<2; i++)
for(int j=0; j<n-i-1; j++)
{
if(a[j] >a[j+1])
swap(a[j], a[j+1]);
}
return a[n-2];
但是这样做,显然效率不够高,几乎要遍历两次,有没有遍历一次就可以找到呢?
第二种思路:
首先看源码:
int find2Max(int a[], int n)
{
int max1 = 0;
int max2 = 0;
for(int i=1; i<n; i++)
{
if(a[i] > a[max1])
{
max2 = max1;
max1 = i;
}
else if(a[i] > a[max2] && a[i] < a[max1])
max2 = i;
}
return max2;
}
首先设置两个索引max1,max2,分别用来存最大的和次最大的索引。然后遍历一次,当a[i] > a[max1]时是一种情况,要进行交换;另外当a[i] < a[max1] 同时a[i] > a[max2]时,这种情况也要进行处理。注意,max1、max2的索引初值均为0, 有的人把max2设成-1,这是不够严密的。另外,就是遍历的时候,从第二个数开始遍历即可,即i = 1开始往后遍历。
这个算法的复杂度是o(n),问题似乎很好解决了,但试问有比这更快的方法吗?而且,如果不是让找第二大的数,而是找第三大、第四大、第五大,或者第三小、第4小的数,上面这种思路显然是走不通的。肿么办? 下篇接着说。