查找n个数中最小的k个元素

来源:互联网 发布:java mysql悲观锁 编辑:程序博客网 时间:2024/04/30 15:14
/* 求n个数中最小的k个元素(n很大,k相对较小) * 建立一个k个元素的堆:再逐个插入,最坏情况时间复杂度为O(nlgk) */#include <stdio.h>/* 求左右叶子、父结点的宏定义 */#define LEFT(i)((i) * 2)#define RIGHT(i) ((i) * 2 + 1)#define PARENT(i)((i) / 2)/* 维持堆的性质 * 算法原理:选取当前结点及其子结点3个中的最大值, *跟当前结点交换,并递归 */void keep_max_heap(int *heap, int size, int i) {int max = i;if (LEFT(i) <= size && heap[LEFT(i)] > heap[max]) {max = LEFT(i);}if (RIGHT(i) <= size && heap[RIGHT(i)] > heap[max]) {max = RIGHT(i);}if (i != max) {int tmp = heap[max];heap[max] = heap[i];heap[i] = tmp;keep_max_heap(heap, size, max);}}/* 根据数组建立堆  * 算法原理:n/2个元素是第一个非叶子结点, * 从该元素往上逐渐调整堆,使之保持堆特性。 * 为方便,数组第0号元素不用 */void build_max_heap(int *heap, int size) {for (int i = size / 2; i > 0; i--) {keep_max_heap(heap, size, i);}}/* 大根堆排序,从小到大 */void max_heap_sort(int *heap, int size) {for (int i = size; i > 0; i--) {int tmp = heap[i];heap[i] = heap[1];heap[1] = tmp;keep_max_heap(heap, i - 1, 1);} //堆排序后从小到大输出}/* 打印堆元素 */void print_heap(int *heap, int size) {for (int i = 1; i <= size; i++) {printf("%-5d", heap[i]);}printf("\n");}/* 若发现在比大根堆最大值要小的元素, * 则用该元素取代堆的根并使堆保持堆特性 */void max_heap_replace(int *heap, int size, int value) {heap[1] = value;keep_max_heap(heap, size, 1);}int main() {/* 测试 */int a[11] = {-1, 67, 7, 34, 5, 69, 24, 78, 58, 62, 64};int b[100];for (int i = 0; i < 100; i++) {b[i] = 100 - i;}int size = 10;//求0到k大的元素build_max_heap(a, size);print_heap(a, size);for (int i = 0; i < 100; i++) {if (b[i] < a[1]) {max_heap_replace(a, size, b[i]);}}max_heap_sort(a, size);print_heap(a, size);return 0;}/* 结果为 78   69   67   62   64   24   34   58   5    71    2    3    4    5    5    6    7    7    8*/

原创粉丝点击