排序系列五:堆排序

上代码咯

//堆排序指利用堆这种数据结构所设计的一种排序算法。至于堆,大家可以先去百度一下堆是个什么东西,我这里主要放大家最需要的代码hhh
//堆是一个近似完全二叉树的结构,分为“最大堆or大根堆or大顶堆”(根节点值大)和“最小堆”。通常最大堆用来升序,最小堆用来降序
//以升序为例,就是把待排序的一堆无序的数a[n],整理成一个大根堆。一般从最后一个非叶子结点开始(此结点为n/2-1),
//从右至左,从下至上进行调整,得到第一个大根堆后将a[0]与最后一个元素交换,交换后,需将除去最后一个元素的其他所有数字
//再次按上面的过程调整成大顶堆,一直这样子持续下去,最后得到升序排列。

#include<iostream>

void change(int &m,int &n)//调换两个数的位置,即为下面的a[0]和a[j]调换位置做准备
{
	int x=m;m=n;n=x;
}
//一定要注意,这两个调换函数形参为引用,不是该值!!!否则这两个函数不起作用。原因大家自行百度!!!
void adjust(int &x,int &y,int &z)//把三个数中最大的放在节点上
{
	if(y>z){if(x<y){int cc=x;x=y;y=cc;}}
	else{if(x<z){int cc=x;x=z;z=cc;}}
}

void sort(int a[],int n)
{
	for(int i=n/2-1;i>=0;i--)//第一次排序,从最后一个节点开始,从右向左,从下向上不断排序,最终将最大值放在a[0]位置
	{
		if(2*i+2==n)//这一个if是用来判断最后的二叉树下面有一个还是两个数字,若只剩一个数字,则a[2*i+2]多余,用a[2*i+1]代替
		{adjust(a[i],a[2*i+1],a[2*i+1]);}
		else
		{adjust(a[i],a[2*i+1],a[2*i+2]);}
	}
	for(int j=n-1;j>0;j--)//之后的多次排序
	{
		change(a[0],a[j]);//将最大的数字放在最后,以后不再对它进行排序,只对前面的排序
		for(int i=j/2-1;i>=0;i--)
		{
			if(2*i+2==j)//用来判断最后的二叉树下面有一个还是两个数字,若只剩一个数字,则a[2*i+2]多余,用a[2*i+1]代替
			{adjust(a[i],a[2*i+1],a[2*i+1]);}
			else
			{adjust(a[i],a[2*i+1],a[2*i+2]);}
		}
	}
}

int main()
{
	int a[]={1,2,3,4,5,6,7,8,9,10,20,19,18,17,16,15,14,13,12,11};
	int n=sizeof(a)/sizeof(a[0]);
	sort(a,n);
	for(int i=0;i<n;i++)//输出排序结果
	{std::cout<<a[i]<<" ";}
	system("pause");
	return 0;
}

运行结果如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值