赞
踩
用堆的数据结构常见解决问题是 TopK 和堆排序。
1 TopK 问题
此问题需要在N个数中找出最大或者最小的K 个数。这里我们用找最大的K个数来举例。
- void AdjustDown(int* hp, int K, int i)
- {
- int parent = i;
- int child = i * 2 + 1;
- while (child < K)
- {
- if (child + 1 < K&&hp[child + 1] < hp[child])
- {
- ++child;
- }
- if (hp[parent]>hp[child])
- {
- swap(hp[child], hp[parent]);
- parent = child;
- child = parent * 2 + 1;
- }
- else
- {
- break;
- }
- }
- }
-
-
- ///TopK问题
- void TopK()
- {
- const int N = 1000; // 假设给随机1000个数
- const int K = 5; //找最大的5个数
- int a[N] = {0};
- for (int i = 0; i < N; ++i)
- {
- a[i] = rand() % 1000; //创建数组a[]
- }
- a[2] = 5000; //给定几个最大的数,以便测试代码时,这几个数一定在其中
- a[62] = 1020;
- a[996] = 8888;
- a[452] = 9999;
-
- int hp[K] = { 0 };
- for (int i = 0; i < K; ++i) //用a[]数组中的K个数创建hp[]这个数组
- {
- hp[i] = a[i];
- }
-
- for (int i = (K - 2) >> 2; i >= 0; --i) 用数组hp建立小堆
- {
- AdjustDown(hp, K, i);
- }
- for (size_t i = K; i < N; ++i) 拿建好的小堆与a[]数比较。(小堆时,hp[0]是堆中最小的数,只要a[i]比它大就交换)
- {
- if (a[i]>hp[0])
- {
- hp[0] = a[i];
- AdjustDown(hp, K, 0);
- }
- }
-
- for (size_t i = 0; i < K; ++i) 打印这个堆,可以看到最大的五个数
- {
- cout << hp[i] << " ";
- }
- cout << endl;
- }
2堆排序问题
思路:若把一组数从小到大排列---》先建立大堆-----》a[0]是堆顶,a[end]是堆的最后一个数,两个交换-----》除去最后一个进行向下调整---》--end ,直到end为0
- void AdjustDown1(int* b, int n, int i) //向下调整,建立大堆
- {
- int parent = i;
- int child = parent * 2 + 1;
- while (child < n)
- {
- if (child + 1 < n&&b[child + 1] > b[child])
- {
- ++child;
- }
- if (b[child]>b[parent])
- {
- swap(b[child], b[parent]);
- parent = child;
- child = parent * 2 + 1;
- }
- else
- {
- break;
- }
- }
- }
-
-
- int b[] = { 10, 11, 1, 2, 3, 85, 96, 4, 23, 52 };
- void SortHeap(int* b, size_t n)//堆排序 升序 --》建立大堆
- {
- for (int i = (n - 2) >> 2; i >= 0; --i)//建堆
- {
- AdjustDown1(b, n, i);
- }
- int end = n - 1; //end 为最后一个数的下标
- while (end) //不断的取堆顶最大的数放到后面,--end,调整堆。
- {
- swap(b[0], b[end]);
- AdjustDown1(b, end,0);
- --end;
- }
- for (int i = 0; i < n; ++i)
- {
- cout << b[i] << " ";
- }
- cout << endl;
- }
2 堆排序:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。