(C语言)数据结构——直接选择排序和堆排序

文章目录

  • 选择排序
    • 1.直接选择排序
    • 2.堆排序

选择排序

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

1.直接选择排序

  • 首先在未排序序列中找到最小(大)元素(看你是排升序还是降序),存放到排序序列的起始位置。
  • 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的后面。
  • 重复第二步,直到所有元素均排序完毕。

(C语言)数据结构——直接选择排序和堆排序_第1张图片
实现代码:
其中a为待排序的数组,n为元素个数

void SelectSort(int* a, int n)
{
	int begin = 0;//开始元素的坐标
	int min = 0;//假设最小元素的坐标
	while (begin<n)
	{
		min = begin;//注意下一次进来要更新坐标
		for (int i = begin+1; i < n; i++)
		{
			if (a[i] < a[min])
			{
				min = i;
			}
		}
		Swap(&a[begin], &a[min]);
		begin++;
	}
}

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

2.堆排序

——对于有不理解的老铁可以看这篇文章(C语言)数据结构二叉树之堆
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆
堆排序即利用堆的思想来进行排序,总共分为两个步骤:

  • 建堆 (升序建大堆 ,降序建小堆)
  • 利用堆删除思想来进行排序

解释:由于堆的特殊特性堆顶元素一定是最大的或者最小的,让堆顶先与下标为n-1的元素交换,交换完再进行向下调整;让堆顶再与下标为n-2的元素交换,交换完再进行向下调整;让堆顶再与下标为n-3的元素交换,交换完再进行向下调整,就这个过程循环往复,直到把下标为1的元素和下标为0的元素交换完成之后停止,堆排序就排好了。
(C语言)数据结构——直接选择排序和堆排序_第2张图片
实现代码:

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void AdjustDown(int* a, int n, int parent)
{
	int minChild = parent * 2 + 1;
	while (minChild < n)
	{
		// 找出小的那个孩子
		if (minChild + 1 < n && a[minChild + 1] > a[minChild])
		{
			minChild++;
		}

		if (a[minChild] > a[parent])
		{
			Swap(&a[minChild], &a[parent]);
			parent = minChild;
			minChild = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

// O(N*logN)
void HeapSort(int* a, int n)
{
	// 大思路:选择排序,依次选数,从后往前排
	// 升序 -- 大堆
	// 降序 -- 小堆
	// 建堆 -- 向下调整建堆 - O(N)
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDown(a, n, i);
	}

	// 选数 N*logN
	int i = 1;
	while (i < n)
	{
		Swap(&a[0], &a[n - i]);
		AdjustDown(a, n - i, 0);
		++i;
	}
}

直接选择排序的特性总结:
1. 堆排序使用堆来选数,效率就高了很多。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(1)
4. 稳定性:不稳定

你可能感兴趣的:(C语言,数据结构,数据结构,c语言,排序算法)