找出无序数组中最大的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;
}
}
}
浙公网安备 33010602011771号