#include <iostream>
using namespace std;
/*
堆排序优势:(二叉堆)
计算机内部:
LEFT: i值左移一位,计算出2i;
RIGHT:i值左移一位,低位加一,计算出2i+1;
PARENT: i/2取下界;
#最大堆性质:除了根节点以外的所有节点i都要满足:
A[PARENT(i)]≥A[i]
堆中的最大元素在根节点,堆排序算法应用
#最小堆性质:除了根节点以外的所有节点i都要满足:
A[PARENT(i)]≤A[i]
堆中的最小元素在根节点,最小堆通常用于构造优先队列
#堆排序算法 HEAPSORT 就是利用最大堆的性质,将当前堆的最后一个元素和整个堆的根节点互换
然后堆的大小减少1,对堆进行MAX_HEAPIFY操作,又得到一个最大堆
最大堆根节点就是当前堆中的最大值,循环整个过程直到堆只剩下一个元素。
#堆排序算法的时间复杂度是 Θ(nlgn)
*/
//定义父节点、左右子节点下标规律
int PARENT(int i) {
return (int)(i / 2) ;
}
int LEFT(int i) {
return 2 * i;
}
int RIGHT(int i) {
return 2 * i + 1;
}
//交换值函数
void swapValue(int &a, int &b) {
int temp;
temp = a;
a = b;
b = temp;
}
//n是数组A的元素数
void MAX_HEAPIFY(int *A,int n,int i) {
int l = LEFT(i);
int r = RIGHT(i);
int largest;
if (l < n && A[l] > A[i])
largest = l;
else
largest = i;
if (r < n && A[r] > A[largest])
largest = r;
if (largest != i)
{
swapValue(A[i], A[largest]);
MAX_HEAPIFY(A, n,largest);
}
}
//堆排序算法
void HEAPSOSRT(int *A,int n) {
for (int i = n-1;i > 1;i--) {
swapValue(A[1], A[i]);
n = n - 1;
MAX_HEAPIFY(A, n, 1);
}
}
int main()
{
int A[11] = {0, 16,4,10,14,7,9,3,2,8,1 };
int B[11] = { 0,4,1,3,2,16,9,10,14,8,7 };
for (int i = 5;i > 0;i--)
MAX_HEAPIFY(B, 11, i);
for (int i = 0;i < 11;i++)
cout << B[i] << " ";
cout << endl;
HEAPSOSRT(B, 11);
for (int i = 0;i < 11;i++)
cout << B[i] << " ";
cout << endl;
return 0;
}
/*
一颗树高为h的节点,MAX_HEAPIFY函数的时间复杂度是O(h)=Θ(lgn)
构建一个最大堆,观察到,元素数为n的二叉堆的[floor(n/2)+1,n]都是叶子节点,所以只要考虑前面的作为父节点的节点是否满足最大堆的要求
所以构建一个二叉堆最大堆的时间复杂度是Θ(nlgn)
*/
//基于最大堆的最大优先序列所支持的操作:
void INSERT(int *S, int x); //把元素x插入到集合S中
int MAXIMUM(int *S); //返回S中具有最大键字的元素
int EXTRACT_MAX(int *S); //去掉并返回S中的具有最大键字的元素
void INCREASE_KEY(int *S, int x, int k); //将元素x的关键字值增加到k,这里假设k的值不小于x的原关键字值
/*
最大优先队列的应用:在共享计算机系统的作业调度,记录各个作业之间的相对优先级并完成调度。
优先队列的所有操作的时间复杂度都是Θ(lgn)
*/
堆排序_C++实现
最新推荐文章于 2024-08-30 11:20:52 发布