下面再介绍STL中与堆相关的4个函数——建立堆make_heap(),在堆中添加数据push_heap(),在堆中删除数据pop_heap()和堆排序sort_heap():
头文件 #include <algorithm>
下面的_First与_Last为可以随机访问的迭代器(指针),_Comp为比较函数(仿函数),其规则——如果函数的第一个参数小于第二个参数应返回true,否则返回false。
建立堆
make_heap(_First, _Last, _Comp)
默认是建立最大堆的。对int类型,可以在第三个参数传入greater<int>()得到最小堆。
在堆中添加数据
push_heap (_First, _Last)
要先在容器中加入数据,再调用push_heap ()
在堆中删除数据
pop_heap(_First, _Last)
要先调用pop_heap()再在容器中删除数据
堆排序
sort_heap(_First, _Last)
排序之后就不再是一个合法的heap了
有关堆与堆排序的更详细介绍请参阅——《白话经典算法系列之七 堆与堆排序》
下面给出STL中heap相关函数的使用范例:
-
- #include <cstdio>
- #include <vector>
- #include <algorithm>
- #include <functional>
- using namespace std;
- void PrintfVectorInt(vector<int> &vet)
- {
- for (vector<int>::iterator pos = vet.begin(); pos != vet.end(); pos++)
- printf("%d ", *pos);
- putchar('\n');
- }
- int main()
- {
- const int MAXN = 20;
- int a[MAXN];
- int i;
- for (i = 0; i < MAXN; ++i)
- a[i] = rand() % (MAXN * 2);
-
-
- vector<int> *pvet = new vector<int>(40);
- pvet->assign(a, a + MAXN);
-
-
- make_heap(pvet->begin(), pvet->end());
- PrintfVectorInt(*pvet);
-
-
- pvet->push_back(25);
- push_heap(pvet->begin(), pvet->end());
- PrintfVectorInt(*pvet);
-
-
- pop_heap(pvet->begin(), pvet->end());
- pvet->pop_back();
- pop_heap(pvet->begin(), pvet->end());
- pvet->pop_back();
- PrintfVectorInt(*pvet);
-
-
- sort_heap(pvet->begin(), pvet->end());
- PrintfVectorInt(*pvet);
-
- delete pvet;
- return 0;
- }
掌握其基本用法后,我们用这个堆排序和《白话经典算法系列》中的堆排序、快速排序,归并排序来进行个性能测试(Win7 + VS2008 Release下),测试代码如下:
-
- #include <cstdio>
- #include <algorithm>
- #include <ctime>
- using namespace std;
-
- void quick_sort(int s[], int l, int r)
- {
- if (l < r)
- {
- int i = l, j = r, x = s[l];
- while (i < j)
- {
- while(i < j && s[j] >= x)
- j--;
- if(i < j)
- s[i++] = s[j];
-
- while(i < j && s[i] < x)
- i++;
- if(i < j)
- s[j--] = s[i];
- }
- s[i] = x;
- quick_sort(s, l, i - 1);
- quick_sort(s, i + 1, r);
- }
- }
-
-
- void mergearray(int a[], int first, int mid, int last, int temp[])
- {
- int i = first, j = mid + 1;
- int m = mid, n = last;
- int k = 0;
-
- while (i <= m && j <= n)
- {
- if (a[i] < a[j])
- temp[k++] = a[i++];
- else
- temp[k++] = a[j++];
- }
-
- while (i <= m)
- temp[k++] = a[i++];
-
- while (j <= n)
- temp[k++] = a[j++];
-
- for (i = 0; i < k; i++)
- a[first + i] = temp[i];
- }
- void mergesort(int a[], int first, int last, int temp[])
- {
- if (first < last)
- {
- int mid = (first + last) / 2;
- mergesort(a, first, mid, temp);
- mergesort(a, mid + 1, last, temp);
- mergearray(a, first, mid, last, temp);
- }
- }
- bool MergeSort(int a[], int n)
- {
- int *p = new int[n];
- if (p == NULL)
- return false;
- mergesort(a, 0, n - 1, p);
- return true;
- }
-
- inline void Swap(int &a, int &b)
- {
- int c = a;
- a = b;
- b = c;
- }
-
-
- void MinHeapFixdown(int a[], int i, int n)
- {
- int j, temp;
-
- temp = a[i];
- j = 2 * i + 1;
- while (j < n)
- {
- if (j + 1 < n && a[j + 1] < a[j])
- j++;
-
- if (a[j] >= temp)
- break;
-
- a[i] = a[j];
- i = j;
- j = 2 * i + 1;
- }
- a[i] = temp;
- }
-
- void MakeMinHeap(int a[], int n)
- {
- for (int i = n / 2 - 1; i >= 0; i--)
- MinHeapFixdown(a, i, n);
- }
- void MinheapsortTodescendarray(int a[], int n)
- {
- for (int i = n - 1; i >= 1; i--)
- {
- Swap(a[i], a[0]);
- MinHeapFixdown(a, 0, i);
- }
- }
- const int MAXN = 5000000;
- int a[MAXN];
- int b[MAXN], c[MAXN], d[MAXN];
- int main()
- {
- int i;
- srand(time(NULL));
- for (i = 0; i < MAXN; ++i)
- a[i] = rand() * rand();
-
- for (i = 0; i < MAXN; ++i)
- d[i] = c[i] = b[i] = a[i];
-
- clock_t ibegin, iend;
-
- printf("--当前数据量为%d--By MoreWindows(http://blog.csdn.net/MoreWindows)--\n", MAXN);
-
- printf("快速排序: ");
- ibegin = clock();
- quick_sort(a, 0, MAXN - 1);
- iend = clock();
- printf("%d毫秒\n", iend - ibegin);
-
-
-
- printf("归并排序: ");
- ibegin = clock();
- MergeSort(b, MAXN);
- iend = clock();
- printf("%d毫秒\n", iend - ibegin);
-
-
- printf("堆排序: ");
- ibegin = clock();
- MakeMinHeap(c, MAXN);
- MinheapsortTodescendarray(c, MAXN);
- iend = clock();
- printf("%d毫秒\n", iend - ibegin);
-
-
- printf("STL中的堆排序: ");
- ibegin = clock();
- make_heap(d, d + MAXN);
- sort_heap(d, d + MAXN);
- iend = clock();
- printf("%d毫秒\n", iend - ibegin);
- return 0;
- }
对100000(十万)个数据的测试结果:

对500000(五十万)个数据的测试结果:

对1000000(一百万)个数据的测试结果:

对5000000(五百万)个数据的测试结果:

从中可以看出快速排序的效率确实要比其它同为O(N * logN)的排序算法要高,而STL中堆操作函数的性能与《白话经典算法系列之七 堆与堆排序》一文中堆操作函数的性能是相差无几的。
转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/6967409