排序算法-堆排序

本文详细介绍了堆排序算法的原理与实现过程。通过构建大顶堆并不断调整以完成排序,堆排序具备O(NlogN)的时间复杂度。文章还提供了完整的C++代码实现,并解释了堆排序属于不稳定但原地的排序方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

堆排序
        优先队列的结构是节点i的孩子为2*i和2*i+1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。优先队列可以以O(NlogN)时间进行排序,基于该思想的算法叫做堆排序。
        首先将数组构造成一个大顶堆,然后在每次deleteMax之后,堆缩小了1,让最后的单元存放刚刚删去的元素,直至最后删掉堆中所有元素,即可得到非递减序列。
        堆排序不是稳定排序,是原地排序。

/************************************堆排序*************************************/
#include <vector>
#include <iostream>

using namespace std;

void heapSort(vector<int> &a);  //堆排序 
int leftChild(int i);           //得到左孩子
void percDown(vector<int> &a,int i,int n); //维持一个大顶堆

int main()
{
	vector<int> ivec(5);
	for(size_t i=0;i<ivec.size();i++)
		cin>>ivec[i];
    heapSort(ivec);
	for(size_t i=0;i<ivec.size();i++)
		cout<<ivec[i]<<"\t";
  system("pause");
  return 0;
}

/*堆排序
* 输入a:待排序的数组
*/
void heapSort(vector<int> &a)
{
	for(int i=a.size()/2;i>=0;i--)      //将a改成一个大顶堆 
		percDown(a,i,a.size());
	for(int j=a.size()-1;j>0;j--)     //循环,
	{
		swap(a[0],a[j]);              //将大顶堆第一个元素和最后一个元素交换
		percDown(a,0,j-1);              //维持一个大顶堆
	}
}

/*求左孩子节点
*/
int leftChild(int i)
{
	return 2*i;
}

/*维持一个大顶堆
*输入a:待排序的数组
*    i:维持大顶堆的起始位置
*    n:大顶堆的节点数目
*/
void percDown(vector<int> &a,int i,int n)
{
	int child;
	int tmp=a[i];             //暂存父节点的值
	while(leftChild(i)<n)  
	{
		
		child=leftChild(i);
		if(child!=n-1&&a[child]<a[child+1])   //如果有右孩子,看左孩子值大还是右孩子值大
			child++;                          //child 为节点值大的孩子
		if(tmp<a[child])                      //如果父节点没有孩子节点值大
			a[i]=a[child];                    //交换孩子节点和父节点
		else
			break;
		i=child;                             //继续修改下面的节点
	}
	a[i]=tmp;                                //将tmp暂存的值给最后的i节点
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值