首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【算法精讲】选择排序、堆排序(C语言)

【算法精讲】选择排序、堆排序(C语言)

作者头像
用户11935701
发布2025-12-16 08:38:20
发布2025-12-16 08:38:20
2470
举报

1.直接选择排序

直接插入排序是一种简单的排序算法,它将数组分为有序和无序两部分,和插入排序的思路有些类似。

时间复杂度:O( N^2)

这里我们拿升序举例,具体思路如下:

  1. 从无序的那边的里面挑出值最小的位置。
  2. 和有序的数组的最后位置交换。
  3. 不断交换直到数组全部有序

图解:

代码如下:

代码语言:javascript
复制
void SleteSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int mini = i, min = a[i];
		for (int j = i; j < n; j++)
		{
			if (a[j] < a[mini])
			{
				min = a[j];
				mini = j;
			}
		}//找最值

		int tmp = a[i];
		a[i] = a[mini];
		a[mini] = tmp;//交换
	}
}

优化:

每次遍历找最大值和最小值,把最大值放后面,最小值放前面。

代码语言:javascript
复制
void Sweap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void SelectSort(int* arr, int n)
{
	int begin = 0, end = n - 1;
	while (begin < end)
	{
		int max = arr[begin], min = arr[begin], maxi = begin, mini = begin;

		for (int i = begin; i <= end; i++)
		{
			if (min > arr[i])
			{
				min = arr[i];
				mini = i;
			}
			if (max < arr[i])
			{
				max = arr[i];
				maxi = i;
			}
				
		}
		
		//这里是特殊情况,避免最大值的位置和begin的位置重复
		
		//判断max的位置是因为要先交换最小值,这块可以仔细想想
		
		if (maxi == begin)
		{
			maxi = mini;
		}
		Sweap(&arr[begin], &arr[mini]);//交换,这里分装成一个函数了
		Sweap(&arr[end], &arr[maxi]);
		begin++;
		end--;

	}
}

2.堆排序

堆排序是直接选择排序的进阶版,他在其原本的思想上进行了优化。

下面的内容涉及一部分数据结构堆的知识,不适合新手学习。

我们依然拿升序举例子,具体步骤如下:

  1. 将所有数据建立成一个大堆。
  2. 利用大堆的结构特点,即堆顶的值是最大值。
  3. 堆顶元素和堆的最后一个数进行交换,并让堆的大小减少1。
  4. 让此时的堆顶元素向下调整,调整后堆顶元素仍会是堆里的最大值。
  5. 循环上述步骤,直到排序完成。

时间复杂度:O( N * logN)

图解如下:

具体代码如下:

代码语言:javascript
复制
void Sweap1(int* a, int* b)
{
	int tem = *a;
	*a = *b;
	*b = tem;
}
void AdjustDown1(int* a, int size, int child)//向下调整的函数
{
	int partent = child;
	child = child * 2 + 1;
	while (child < size)
	{
		if (child + 1 < size && a[child] > a[child + 1])
			child++;
		if (a[child] < a[partent])
		{
			Sweap1(&a[child], &a[partent]);
			partent = child;
			child = child * 2 + 1;

		}
		else
		{
			break;
		}
	}
}


void HeapSort(int* a, int n)
{
	int end =  n - 1;
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)//从倒数第二层的最后一个元素开始的
	{
		AdjustDown1(a, i, 0);
	}

	while (end > 0)
	{
		Sweap1(&a[end], &a[0]);
		AdjustDown1(a, end, 0);//向下调整;
		end--;
	}
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.直接选择排序
  • 2.堆排序
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档