基本排序(2)——选择排序

本文介绍了选择排序和堆排序的基本原理及其实现方法。选择排序通过遍历数组找到最大或最小值并放置于序列末端来完成排序;堆排序则是利用大根堆或小根堆的特性,每次将堆顶元素与堆尾交换并调整剩余元素为新的堆结构,以此达到排序目的。

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

 

目录

前言

选择排序

    代码实现

堆排序

    代码实现


前言

    选择排序应该是最好理解的排序算法,核心思想就是在遍历数组找最大或最小的值将其放在最后,然后循环次数减一再重复以上操作。

    由此可知选择排序是不稳定的排序。

    选择排序也有一定缺陷,他会重复比较前面一些较小或较大元素,其时间复杂度为O(N^2)

相比之下堆排序效率更高。

选择排序

    例如一个无序序列 5 1 2 3 4 0  ,我们先寻找里面的最大值5,找到后将5与最后一位元素交换,

然后循环的次数减一,再从剩下的序列中找最大值与最有一位元素交换,直到循环次数len小于2退出。

 

    代码实现

void SelectSort(int* a, int n){ //n为数组长度
	int max = 0;  //max初始化为0号下标
	int len = n;  //用len记录数组长度
	while (len>1){ //循环条件
		for (int i = 0; i < len; ++i){
			if (a[max] < a[i])  //遇到大于max下标的值时,max被赋值成该下标
				max = i;
		}
		//循环结束后max下标上的值是最大的
		Swap(&a[max], &a[len - 1]); //交换max和数组最后一位
		len--;  //循环次数减一
		max = 0;  //一定要将max置0
	}
}

    可以对以上代码进行一点小改进,每趟不仅找到最大值,还要找到最小值将最小值与最前面元素交换,然后循环次数减二,这样做虽然循环次数减半了,但时间复杂度没有变。

堆排序

    堆排序也是选择排序的一种,如果要升序则建堆时选择大堆,降序选小堆。

    核心思想就是,每次将堆顶元素和堆尾元素进行交换,如果是大堆的话,那么最大的元素就跑到了堆尾,然后除开堆尾,将剩下的元素重新排成大堆,再重复以上操作。

    代码实现

   

void AdjustDwon(int* a, int start, int end){
	int tmp = a[start];
	for (int i = 2 * start + 1; i <= end; i = i * 2 + 1)
	{
		if (i < end&& a[i] < a[i + 1])//有右孩子并且左孩子小于右孩子
		{
			i++;
		}//i一定是左右孩子的最大值
		if (a[i] > tmp)
		{
			a[start] = a[i];
			start = i;
		}
		else
		{
			break;
		}
	}
	a[start] = tmp;
	
}

void HeapSort(int* a, int n){
	//升序的话第一次建立大根堆,从后往前依次调整
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDwon(a, i, n - 1);
	}
	//每次将根和待排序的最后一次交换,然后在调整
	int tmp;
	for (int i = 0; i < n - 1; i++)
	{
		tmp = a[0];
		a[0] = a[n - 1 - i];
		a[n - 1 - i] = tmp;
		AdjustDwon(a, 0, n - 1 - i - 1);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值