求数组的最大值,次大值

在期末微机原理考试的时候,老师给我们出了一个题是求一段数的最大值,次大值,当时题目的要求使用汇编语言写的,这里我使用C++将相关算法表现出来。

求数组的最大值是很简单的,基本上每个会编程的人都会求,但是求次大值就稍微有点弯了……

我当时的思路是这样的:

因为这一段数字都是正整数,所以我通过两次循环比较来实现,第一次遍历求得最大值,然后将最大值对应的位置的数字置零,第二次遍历求得次大值。

两次遍历的方法:

#include<iostream>
using namespace std;
int fun_max(int *a,int n)
{
	int max=a[0],k=0;
	for(int i=1;i<n;i++)
	{
		if(max<a[i])
		{
			max = a[i];
			k = i;		//用k保存最大值的位置 
		}
	}
	a[k] = 0;	//最大值置零 
	return max; 
}
int main()
{
	int a[5]={1,40,6,7,10};
	cout<<"m1:"<<fun_max(a,5)<<endl;	//求得最大值并输出,然后将最大值置零 
	cout<<"m2:"<<fun_max(a,5)<<endl;	//求得最大值置零之后的最大值,也就是次大值 
	return 0;
}

这样做的是完全符合题意的,输出结果也是正确的,但是这样无疑破坏了数组中原来的数据(虽然题目中没有说不可以修改数组中的数据),并且进行了两次遍历,总感觉方法不是很好。

考完之后,和同学交流知道了一种更好的方法,一种通过一次遍历就可以得到结果,并且不会修改数组中数据的方法:

让数组中的每个数和最大值比较:

如果a[i]>m1,就说明目前的“最大值m1”并不是最大值,而是a[i],所以将当前的最大值赋给次大值,然后将a[i]赋给m1;

如果a[i]<=m1,然后判断ai]>m2是否成立,如果a[i]是小于最大值并且大于“次大值”的数,那个a[i]就是新的次大值。

一次遍历的方法:

#include<iostream>
using namespace std;
int main()
{
	int a[5]={1,40,6,7,10};
	int m1=a[0],m2=a[0];
	for(int i=1;i<5;i++)
	{
		if(m1<a[i])
		{
			m2=m1;
			m1=a[i];	
		}
		else
		{
			if(m2<a[i])m2=a[i];
		}
	}
	cout<<"m1:"<<m1<<endl;
	cout<<"m2:"<<m2<<endl;
	return 0;
}

这个方法明显要好得多……


当然,排序也是一种方法,一种思路是自己写排序算法,不过,我们没有必要对这5个数都进行排序,只需要找到获得排序结果的前两个;另一种方法是利用stl中的排序算法,这种方法使用简单,但是无疑是做了一些无用功。

排序方法:

使用选择排序法:
#include<iostream>
using namespace std;
int main()
{
	int a[5]={1,40,6,7,10};
	int k,temp;
	for(int i=0;i<2;i++)	//a[0] 和a[1]分别是最大和次大 
	{
		k = i;
		for(int j=i;j<5;j++)
		{
			if(a[j]>a[k])k=j;
		}
		temp = a[k];
		a[k] = a[i];
		a[i] = temp;
	}
	cout<<"m1:"<<a[0]<<endl;
	cout<<"m2:"<<a[1]<<endl;
	return 0;
}

使用stl的快速排序算法: 

#include<iostream>
#include<cstdlib>
using namespace std;
int  com(const void *a,const void *b)
{
	return *(int *)a < *(int *)b;
}
int main()
{
	int a[5]={1,40,6,7,10};
	qsort(a,5,sizeof(a[0]),com);
	cout<<"m1:"<<a[0]<<endl;
	cout<<"m2:"<<a[1]<<endl;
	return 0;
}

输出结果:

m1:40

m2:10





posted @ 2014-02-08 14:39  千手宇智波  阅读(3138)  评论(0编辑  收藏  举报