【选择排序——直接选择和堆排序】


基本思想:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的
数据元素排完 。

直接选择排序

在元素集合array[i]–array[n-1]中选择关键码最大(小)的数据元素
若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
在剩余的array[i]–array[n-2](array[i+1]–array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

交换函数

void swap(int* px , int* py)
{
	int tmp = *px;
	*px = *py;
	*py = tmp;
}
// 选择排序
void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n-1;
	while(begin<end)
	{
		int maxi = begin,mini = begin;
		//先单趟循环,找最大和最小的
		forint i = begin;i<=end; ++i)
		{
			if(a[i] < a[mini])
				mini = i; 
				
			if(a[i] > a[maxi])
			  	maxi = i;
			  	
		}
		//最大最小值与头尾交换
		swap(&a[begin],&a[mini]);
		// begin == maxi时,最大被换走了,得修正一下maxi的位置
		if(begin == maxi)
		maxi = mini;
		
		swap(&a[maxi],&a[end]);
		//单趟循环
		++begin;
		--end;
}

直接选择排序的特性总结:

  1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

//向下调整
void AdjustDown(int* a, int n, int parent)
{	
	int child = parent * 2 + 1;
	while(child < n)
	{
		//选出左右孩子中大的那一个
		if(child+1 < n && a[child+1] > a[child])
		{
			++child;
		}
		// 如果小的孩子大于父亲,则交换,并继续向下调整
		if(a[child] > a[parent])
		{
			swap(&a[child],&a[parent]);
			parent = child;
			child = parent*2 + 1;
		}
		else
		{
			break;
		}
	}
}
//堆排序
void HeapSort(int* a, int n)
{
	//先建大堆,倒着走从最后一个非叶子节点的子树向下调整
	for(int i = (n-1-1)/2 ; i >= 0 ; --i)
	{
		AdjustDown(a, n ,i);
	}
	int end = n-1;
	//找到最大的数据,将最大的数据和最后一个节点数据交换
	//之后--end,向下调整一次找到次大的数据,依次循环
	while(end > 0)
	{
		swap(&a[0],&a[end]);
		--end;
		AdjustDown(a, n ,0);
	}	
}

在这里插入图片描述
直接选择排序的特性总结:

  1. 堆排序使用堆来选数,效率就高了很多。
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值