堆排序_C++实现

#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)
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值