求找出一个整型数组中的第二大元素的函数

随风Marz 2012-03-14 10:04:17
求找出一个整型数组中的第二大元素的函数
...全文
2232 43 打赏 收藏 转发到动态 举报
写回复
用AI写文章
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
kosora曹 2013-08-19
  • 打赏
  • 举报
回复
同意40楼的观点,如果是面试题,面试官十有八九考你对堆排序的掌握程度。
woshinia 2013-08-16
  • 打赏
  • 举报
回复
1,是快取算法,这个网上很多。 2,是维护一个最大堆,并且保持堆的大小为k,即比这k个都小的直接丢,比其中一个大就插入,然后丢弃最小的那个,只需遍历一次。比较的复杂度为k*n。
田贝 2013-08-15
  • 打赏
  • 举报
回复

//放回数组pArr中第二大的元素的下标。
int findElemAt(int * pArr ,int length)
{
	//max_index始终指向最大元素,second_max_index始终指向第二大元素。
	int max_index = 0 , second_max_index = 1;
	assert(length>=2);

	//调整max_index和second_max_index,初始化;
	max_index = pArr[0] > pArr[1] ? 0 : 1 ;
	second_max_index = !max_index;

	for(size_t i = 2 ;i < length ;i++)
	{
		if(pArr[i] > pArr[second_max_index])
		{
			if(pArr[i] > pArr[max_index])
			{
				second_max_index = max_index ;
				max_index = i;
			}
			else
			{	
				second_max_index = i;
			}
		}
	}
	return second_max_index;
}
rocktyt 2013-08-15
  • 打赏
  • 举报
回复
竟然挖坟 lz竟然没结帖 c++里有nth_element,直接参照其代码就好了吧……
WizardOz 2013-08-15
  • 打赏
  • 举报
回复
引用 10 楼 xiaoma435 的回复:
[Quote=引用 4 楼 abc225dingdong 的回复:] 用快排的思想,分治,可以用线性时间求任意第k大的数 [/Quote]这个方法倒是不错,不过不知道可不可以帮忙写一下代码??谢谢!
请参考《算法导论》“中位数”章节。
nice_cxf 2013-08-15
  • 打赏
  • 举报
回复
第k个用最大堆排序,时间复杂度 o(n*lgk),空间复杂度o(k)
lty369963 2013-08-15
  • 打赏
  • 举报
回复
选择排序,鉴定完毕!
大尾巴猫 2013-08-15
  • 打赏
  • 举报
回复
不需要完整排序,用快排的分区实现类似折半查找
//找1个数组中第K大的数
//利用快排分区,实现类似折半查找
#include <iostream>
using namespace std;

bool findk(int* data, int num, int k, int* out);
int partition(int* data, int low, int high);

int main()
{
	int data[] = {1, 7, 4, 8, 5, 6, 3, 2, 0, 9};
	int num = sizeof(data) / sizeof(int);
	int k = 2;  //第k大
	int result;
	if (findk(data, num, k, &result))
		cout << result << endl;
	else
		cout << "not find\n";
	return 0;
}

bool findk(int* data, int num, int k, int* out)
{
	if (num <= 0 || k <= 0 || k > num)
		return false;
	int pos = num - k; //从小到大排序好的数组第pos个下标的数就是第k大的数
	//初始边界
	int low = 0;
	int high = num - 1;
	int middle = partition(data, low, high);
	while (middle != pos)
	{
		if (middle < pos)  //返回坐标小,往右边找
		{
			low = middle + 1;
			middle = partition(data, low, high);
		}
		else       //返回坐标大,往左边找
		{
			high = middle - 1;
			middle = partition(data, low, high);
		}
	}
	*out = data[middle];
	return true;
}

int partition(int* data, int low, int high)  //快排分区函数
{
	if (low == high)
		return low;
	
	int i, j, temp;
	i = (low + high) / 2;
	temp = data[i];  //取中间位置的值做为目标值
	data[i] = data[low]; //把第一个放在中间
	i = low;
	j = high;
	while (i < j)
	{
		while (temp < data[j] && i < j)   //从右往左扫描小于目标的值,应该放在左半部分
			j--;
		if (i < j)                        //找到后放在左边
			data[i++] = data[j];
		else
			break;
		while (temp > data[i] && i < j)   //从左往右扫描大于目标的值,要放在右边
			i++;
		if (i< j)
			data[j--] = data[i];
		else
			break;
	}
	data[i] = temp;                       // i = j,正好是分界线,回填目标值
	return i;
}
AndyStevens 2013-08-15
  • 打赏
  • 举报
回复
用堆排序生成优先级队列
mnxm 2013-08-15
  • 打赏
  • 举报
回复

        static void Main(string[] args)
        {
            int[] arr = new int[] {2,5,4,1,3,7,9,6,8 };
            Console.WriteLine(arr.Except(new int[] { arr.Max() }).Max());
            Console.ReadLine();
        }
赵4老师 2013-08-15
  • 打赏
  • 举报
回复
要考虑以下特殊情况: 空数组 一个元素的数组 ≥两个元素的数组 数组中值全部相同 数组中第二大的元素不唯一
h_l_2011 2012-07-20
  • 打赏
  • 举报
回复
赞成15楼的想法,个人认为,也可以先求出最大,之后利用其他元素与最大值的差值比较,差值最小的元素即为第二大元素,复杂度貌似为0(n)
赵4老师 2012-07-20
  • 打赏
  • 举报
回复
提醒:
·整形数组就一个元素咋办?
·整形数组中的数全相同咋办?
Mosaics_ 2012-07-20
  • 打赏
  • 举报
回复
for(int i = 0,i<数组长度-1,i++)

int temp = a[i]>a[i+1]?a[i+1]:a[i]
hwcheng555 2012-03-18
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 shyrgst 的回复:]
我的想法是,不需要排序
你既然只要第二大,就先找到最大,记下他的下标
然后跳过他在数组中找最大就可以了。
比较简单。
[/Quote]
支持 好方法
maintian 2012-03-18
  • 打赏
  • 举报
回复
#8 有bug,数组前面两个值相等并且是最大的情况。
elegant87 2012-03-18
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 muyi66 的回复:]

一次循环就足够了,先排序是偷懒的做法。

一直保留着最大的两个元素的记录,有超越它们的就更新记录。遍历一次之后就能找出来了。
[/Quote]
用空间换取时间的做法
JackBurd 2012-03-18
  • 打赏
  • 举报
回复
看了一下,和楼上一样。
#include<stdio.h>

void main()
{
int a[8] = {8,9,1,5,6,3,2,7};
int biggest, bigger;

if(a[0] >= a[1])
{
biggest = a[0];
bigger = a[1];
}
else
{
biggest = a[1];
bigger = a[0];
}

for(int i = 2; i < 8; i ++)
{
if(a[i] > bigger)
{
if(a[i] > biggest)
{
bigger = biggest;
biggest = a[i];
}
else
{
bigger = a[i];
}
}
}

printf("biggest = %d, bigger = %d\n", biggest, bigger);
}
LittleCommit 2012-03-18
  • 打赏
  • 举报
回复
int func(int ary[],int nCount)
{
if (nCount < 2)
{
return -1;
}

int nNum1 = 0;
int nNum2 = 0;
if (ary[0] >= ary[1])
{
nNum1 = ary[0];
nNum2 = ary[1];
}
else
{
nNum2 = ary[0];
nNum1 = ary[1];
}

for (int i = 2; i < nCount; ++i)
{
if (ary[i] > nNum1)
{
nNum2 = nNum1;
nNum1 = ary[i];
}
else if (ary[i] > nNum2)
{
nNum2 = ary[i];
}
}

return nNum2;//这个就是第二大的数
}

函数改造了一下,我刚试了,应该可以
muyi66 2012-03-18
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 hwcheng555 的回复:]

引用 15 楼 shyrgst 的回复:
我的想法是,不需要排序
你既然只要第二大,就先找到最大,记下他的下标
然后跳过他在数组中找最大就可以了。
比较简单。

支持 好方法
[/Quote]不是好方法,需要两遍扫描才能完成。仅仅是比先排序稍好一点。
加载更多回复(23)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧