找出无序数组中最大的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; } } }