查找数组中前K个大的和小的元素
来源:互联网 发布:想学做淘宝怎么学 编辑:程序博客网 时间:2024/05/12 23:48
一、查找第K大的元素的算法思想
将数组前K个元素构建一个小顶堆,扫描数组后面的元素,与堆顶元素比较,如果比堆顶元素大,就替换堆顶元素,并重新调整堆;否则继续扫描后续元素。最后将堆中的元素逆序排序。
二、查找第K小的元素
将数组前K个元素构建一个大顶堆,扫描数组后面的元素,与堆顶元素比较,如果比堆顶元素小,就替换堆顶元素,并重新调整堆;否则继续扫描后续元素。最后将堆中的元素升序排序。
/* * ===================================================================================== * * Filename: frontkthnumbers.cpp * * Description: 找出数组中前K个大或小的数 * * Version: 1.0 * Created: 2012年11月25日 16时11分31秒 * Revision: none * Compiler: gcc * * Author: Xingwang Su (http://blog.csdn.net/njzhiyuan) * Organization: * * ===================================================================================== */#include <iostream>#include <vector>#include <string>extern "C" {#include <stdlib.h>#include <sysexits.h>}using namespace std;template <typename T>class ArrayElemt {public:explicit ArrayElemt(size_t pos, const T &val);explicit ArrayElemt(){}inline size_t get_pos();inline T get_val();inline bool operator < (const T &val) const;inline bool operator > (const T &val) const;template <typename C>friend inline bool operator < (const ArrayElemt<C> &a, const ArrayElemt<C> &b);template <typename C>friend inline bool operator < (const C &val, const ArrayElemt<C> &ae);template <typename C>friend inline bool operator > (const ArrayElemt<C> &a, const ArrayElemt<C> &b);template <typename C>friend inline bool operator > (const C val, const ArrayElemt<C> &ae);template <typename C>friend ostream & operator << (ostream &os, const ArrayElemt<C> &ae);private:size_t pos;T val;};template <typename T> ArrayElemt<T>::ArrayElemt(size_t pos, const T &val) : pos(pos), val(val) {}template <typename T>size_t ArrayElemt<T>::get_pos() {return pos;}template <typename T>T ArrayElemt<T>::get_val() {return val;}template <typename T>bool ArrayElemt<T>::operator < (const T &val) const {return this->val < val;}template <typename T>bool operator < (const ArrayElemt<T> &a, const ArrayElemt<T> &b) {return a.val < b.val;}template <typename T>bool operator < (const T &val, const ArrayElemt<T> &ae) {return val < ae.val;}template <typename T>bool ArrayElemt<T>::operator > (const T &val) const {return this->val > val;}template <typename T>bool operator > (const T &val, const ArrayElemt<T> &ae) {return val > ae.val;}template <typename T>bool operator > (const ArrayElemt<T> &a, const ArrayElemt<T> &b) {return a.val > b.val;}template <typename T>ostream & operator << (ostream &os, const ArrayElemt<T> &ae) {os << "[" << ae.pos << "] = " << ae.val;return os;}//计算左子树根节点下标,注意下标从0开始inline size_t left_child(size_t parent) {return parent * 2 + 1;}// 调整大顶堆template <class CD>void maxheap_adjust(vector<CD> &arr, size_t start, size_t end) {CD tmp = arr[start];for (size_t child = left_child(start); child < end; child = left_child(child)) {if (child < end - 1 && arr[child] < arr[child + 1]) ++child;if (tmp > arr[child])break;arr[start] = arr[child];start = child;}arr[start] = tmp;}//调整小顶堆template <class CD>void minheap_adjust(vector<CD> &arr, size_t start, size_t end) {CD tmp = arr[start];for (size_t child = left_child(start); child < end; child = left_child(child)){if (child < end - 1 && arr[child] > arr[child + 1])++child;if (tmp < arr[child])break;arr[start] = arr[child];start = child;}arr[start] = tmp;}template <class CD>void build_heap(vector<CD> &arr, void (*adjust)(vector<CD> &, size_t, size_t)) {for(size_t child = arr.size() / 2; child > 0; --child)adjust(arr, child, arr.size());//size_t类型变量的特殊性,其值总是大于等于0adjust(arr, 0, arr.size());}template <typename T>void heap_sort(vector<T> &arr, void (*adjust)(vector<T> &arr, size_t, size_t)) {build_heap(arr, adjust);for(size_t index = arr.size() - 1; index > 0; --index) {swap(arr[0], arr[index]);adjust(arr, 0, index);}}template <typename T>inline bool less_than(const ArrayElemt<T> &a, const T &b) {return a < b;}template <typename T>inline bool greater_than(const ArrayElemt<T> &a, const T &b) {return a > b;}template <typename T>vector<ArrayElemt<T> > findfrontkthnums(const vector<T> &arr, size_t kth, bool (*compare)(const ArrayElemt<T> &, const T &), void (*adjust)(vector<ArrayElemt<T> >&, size_t, size_t)) {vector<ArrayElemt<T> > frontend;size_t index;for(index = 0; index < kth; ++index) {frontend.push_back(ArrayElemt<T>(index, arr[index]));}build_heap(frontend, adjust);for(index = kth; index < arr.size(); ++index) {if (compare(frontend[0], arr[index])) {frontend[0] = ArrayElemt<T>(index, arr[index]);adjust(frontend, 0, kth);}}heap_sort(frontend, adjust);return frontend;}template <typename T>void createvalue(vector<T> &arr, int seed = 100) {size_t index = 0;srand((unsigned) time(NULL) + seed);while (index != arr.size()) {arr[index++] = static_cast<T>(rand() % seed);}}template <typename T>void display_vector(const vector<T> &arr, const string &prefix = "", const string &suffix = " ") {for(size_t index = 0; index != arr.size(); ++index)cout << prefix << arr[index] << suffix;cout << endl;}int main(int argc, char *argv[]) {vector<long> array(20);size_t kth = 5;vector<ArrayElemt<long> > frontend;createvalue(array);cout << "原始的数列如下:" <<endl;display_vector(array);frontend = findfrontkthnums(array, kth, less_than, minheap_adjust);cout << "前 " << kth << " 个大的元素是:" << endl;display_vector(frontend, "array", ", ");frontend = findfrontkthnums(array, kth, greater_than, maxheap_adjust);cout << "前 " << kth << " 个小的元素是:" << endl;display_vector(frontend, "array", ", ");cout << "排序后数列如下:" <<endl;heap_sort(array, maxheap_adjust);display_vector(array);return EX_OK;}
执行:
$ g++ --version
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright © 2012 Free Software Foundation, Inc.
本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;
包括没有适销性和某一专用目的下的适用性担保。
$ g++ -o frontkthnumbers frontkthnumbers.cpp
$ ./frontkthnumbers
原始的数列如下:
3 65 1 4 97 48 4 85 47 5 4 36 97 22 26 91 67 2 61 5
前 5 个大的元素是:
array[12] = 97, array[4] = 97, array[15] = 91, array[7] = 85, array[16] = 67,
前 5 个小的元素是:
array[2] = 1, array[17] = 2, array[0] = 3, array[6] = 4, array[10] = 4,
排序后数列如下:
1 2 3 4 4 4 5 5 22 26 36 47 48 61 65 67 85 91 97 97
- 查找数组中前K个大的和小的元素
- 查找数组中第K大和第K小的元素
- 数组第k小的元素和数组前k小元素
- 网易_在数组中查找前K个元素
- 在一个数组中找到前k个小(大)的数
- 查找数组中第k小的元素
- 微软试题:查找数组中最小的k个元素
- 在一个数组中查找最大的K个元素或者最小的K个元素
- 查找最小的k个元素(数组)
- 算法之查找第k小的数和查找最小的k个元素
- 求数组中第k个小的元素
- 找包含N个元素的数组里第K大的元素(引申:快速排序、找中位数、找前K大的元素)的时间复杂度
- 查找数组中第K大元素
- 数组中第K大的元素
- 查找数组的前K个最小值的算法
- 找一个数组中的前k小的元素
- Find K-th Smallest Pair Distance:查找数组元素中差值第K大的两个元素的差值
- data_struction_test1:查找数组的前k个最小值
- 得到本机ip
- 你必须知道的28个HTML5特征、窍门和技术
- 如何合并apk和odex
- a letter and a number
- Python获取磁盘空闲空间并写入日志
- 查找数组中前K个大的和小的元素
- 抽屉原理
- HTTP状态码大全
- Redis视频教程
- 【2012年腾讯俱乐部ACM赛新手组1001】简单大数取余-99 division
- AlertDialog类的使用
- 在Linux中开机自动运行普通用户脚本程序
- 推荐背诵的10篇美文
- 生命的真实在每一刻