找出无序数组中最大的N个元素的位置

最简单的方法是对整个数组排序。但是当数组元素比较多而N比较小的时候很划不来(排序复杂度O(nlogn))。

下面的代码对只需对数组的前N个元素排序,然后对数组线性扫描一次即可。查找结果根据元素大小从大到小排列。

参考了stackoverflow.com上找出最大的两个元素位置的代码

// 排序结构和比较函数
struct sort_item { float value; int pos; };

int comp_item(const void * a, const void * b)
{
	float v1 = ((struct sort_item *)a)->value;
	float v2 = ((struct sort_item *)b)->value;
	return (v1<v1) ? -1 : (v1>v2) ? 1 : 0;
}

// 将存放有ary_N个元素的数组value中最大的max_N数的位置找出来,下标存在pos数组中
void largest_N(float * value, int ary_N, int * pos, int max_N)
{
	// 对数组前max_N个元素排序
	struct sort_item sort_items[max_N];
	for (int i = 0; i < max_N; i++)
	{
		sort_items[i].value = value[i];
		sort_items[i].pos = i;
	}
	qsort(sort_items, max_N, sizeof(struct sort_item), comp_item);
	for (int i = 0; i < max_N; i++)
	{
		pos[i] = max_N - 1 - sort_items[i].pos;
	}

	// 线性扫描数组剩余元素
	for (int i = max_N; i < ary_N; i++)
	{
		int j = 0;		
		for (j = 0; j < max_N; j++)
			if (value[i] >= value[pos[j]]) 
				break;
		if (j < max_N)
		{
			for (int k = max_N - 1; k > j; k--)
			{
				pos[k] = pos[k-1];
			}
			pos[j] = i;
		}
	}
}

 

还有一个不对前N元素排序的版本。速度稍慢,不过代码更简单。

// 将存放有ary_N个元素的数组value中最大的max_N数的位置找出来,下标存在pos数组中
void largest_N(float * value, int ary_N, int * pos, int max_N)
{
	// 初始化
	float max_value[max_N];
	for (int i = 0; i < max_N; i++)
	{
		max_value[i] = -FLT_MAX;
		pos[i] = -1;
	}

	// 线性扫描数组元素
	for (int i = 0; i < ary_N; i++)
	{
		int j = 0;
		for (j = 0; j < max_N; j++)
			if (value[i] >= max_value[j]) 
				break;
		if (j < max_N)
		{
			for (int k = max_N - 1; k > j; k--)
			{
				max_value[k] = max_value[k-1];
				pos[k] = pos[k-1];
			}
			max_value[j] = value[i];
			pos[j] = i;
		}
	}
}
posted @ 2010-01-12 15:53  chyojn  阅读(1129)  评论(0编辑  收藏  举报