查找最小的k个元素(数组)

本文介绍了一种通过最小K个数的最大堆来查找数组中最小的K个数的高效算法,包括插入堆、调整堆和弹出堆的操作,以及如何处理堆满的情况。适用于数据量不大的场景,提供了复杂度分析和实际代码实现。

// 5.查找最小的k个元素(数组)

// 题目:输入n个整数,输出其中最小的k个。 // 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。 // 注: // 1 在数据量不大的情况下,排序 // 2 维护一个最小k 的数组 ,复杂度 为 o(k * N) // 3 为一个最小K个数的最大堆 o(log2 k * N)

//每次看这些小算法都不以为然,每次都巨耗时间,比我想象的要多的多啊.....

#include <iostream> #define N 30 using namespace std; int gheap[N] = {0}; int count = 0; void insertheap(int heap[],int data); void adjustheap(int heap[]); void popheap(int heap[], int &); int main() { int data[] = {3,54,65,3,65,7,54,3,23,2,56,54,34}; int k; cin>>k; if (k<0) { cout<<"k should be bigger than 0"<<endl; return 0; } for (int i=0; i<sizeof(data)/sizeof(int); ++i) { if (count<k) { insertheap(gheap,data[i]); } else { if (data[i]< gheap[0]) { int d; popheap(gheap,d); //将最大剔除,将比其小的加入 insertheap(gheap,data[i]); } } } // while (count) // { // int d; // popheap(gheap,d); // cout<<d<<" "; // } for (int j=0; j<k; j++) { int d; popheap(gheap,d); cout<<d<<" "; } cout<<endl; return 0; } void swapdata(int &a, int &b) { int temp; temp = a; a = b; b = temp; } void insertheap(int heap[],int data) { int curpos,parent; if (count>=N) { cout<<"error:heap is full"<<endl; return; } heap[count] = data; curpos = count++; while(curpos) { parent = curpos / 2; if (heap[curpos] > heap[parent]) { swapdata(heap[curpos], heap[parent]); curpos = parent; } else { break; } } } void adjustheap(int heap[]) { int bigchild; if (count<2) { return; } for (int i=0; 2*i<count; i++) { bigchild = 2*i+1; if (bigchild+1< count && heap[bigchild+1]>heap[bigchild]) //choose the bigger child { bigchild++; } if (heap[i]<heap[bigchild]) { swapdata(heap[i], heap[bigchild]); } } } void popheap(int heap[], int &data) { if (count==0) { cout<<"heap empty"<<endl; return; } data = heap[0]; heap[0] = heap[--count]; adjustheap(heap); }

转载于:https://www.cnblogs.com/legendmaner/archive/2012/10/12/2721961.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值