选择排序与堆排序

选择排序与堆排序_第1张图片

个人名片:

作者简介:一名乐于分享在学习道路上收获的大二在校生
‍❄个人主页:GOTXX

个人WeChat:ILXOXVJE
本文由GOTXX原创,首发CSDN

系列专栏:零基础学习C语言----- 数据结构的学习之路
每日一句:如果没有特别幸运,那就请特别努力!
————————————————


目录

1.选择排序

1.1选择排序的基本思想

图解:

1.2代码实现

1.3性能分析

2.堆排序

2.1堆排序的基本思想

图解:

2.2代码实现

2.3性能分析


1.选择排序

1.1选择排序的基本思想

基本思想:

遍历一遍待排数据,将最大值与最小值的下标记录,然后把最小值与数组最前面的数据交换,将最大值与数组最后一个数据交换,这样遍历一遍,就将最大值和最小值放到了正确的位置;

将除了上面已经在正确位置的数据,将剩下的数据看成待排数组,然后重复上述操作,这样,遍历2/n次,就可以将所有数据排好序;

图解:

选择排序与堆排序_第2张图片

1.2代码实现
void SelectSort(int* a, int n)
{
	for (int j = 0; j < n/2; j++)
	{
     //假设数组中最大最小值的下标是j
		int maxi = j;
		int mini = j;
		for (int i = j; i < n -j; i++)
		{
    //有比max大的,就改变下标
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
    //有比min小的,就改变下标
			if (a[i] < a[mini])
			{
				mini = i;
			}
		}
   //将找到的最小值放到待排数组最前面
		Swap(&a[mini], &a[j]);
   //如果最大值在待排数组最前面,在把最小值换到前面的时候,会将最大值的下标改变
   //所以这里需要更新最大值的下标,如上图第三步中8的交换
		if (maxi == j)
		{
			maxi = mini;
		}
   //将最大值放到待排数组的后面
		Swap(&a[maxi], &a[n - 1-j]);
	}
}

1.3性能分析

最坏情况:逆序

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

空间复杂度:O(1)

2.堆排序

要了解堆排序要先了解堆,堆的相关知识http://t.csdnimg.cn/GoxJO

2.1堆排序的基本思想

利用大堆的特点,父亲都大于孩子,所以堆的根结点是整个二叉树中的最大数;

先将根结点与树中最后一个节点交换(对应在数组中,就是将数组中第一个数据与最后一个数字交换),这样,最大的数就在数组最后,在正确的位置上了,交换过后,(树的左右子树都是大堆)这样再利用向下调整建堆,将剩下的数据变成大堆,这样最大的数据又在根结点了,重复上面操作就可以将所有数据变成有序;

图解:

选择排序与堆排序_第3张图片

2.2代码实现

void Adjustdown(int* a, int parent, int n)
{
	assert(a);
	int child = parent * 2 + 1;
	while (child < n)
	{
		//假设左孩子大
		if (child + 1 < n && a[child] < a[child + 1])
		{
        //假设不成立,调整
			child = child + 1;
		}
		if (a[child] > a[parent])
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = child * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
void HeapSort(int* a, int n)
{
	assert(a);

	//从最后一个非叶子节点向下调整
	//n-1是最后一个结点,(n-1-1)/2是它父亲
	for (int i = (n-1-1) / 2; i >= 0; i--)
	{
		Adjustdown(a, i, n);
	}

	int end = n-1;
	while (end > 0)
	{
		Swap(&a[0],&a[end]);
		Adjustdown(a,0, end);
		end--;
	}
}

2.3性能分析

数据个数为N,则高度为:logN

N个数据,每个数据向下调整,时间复杂度需要logN

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

空间复杂度为:O(N)


你可能感兴趣的:(数据结构的学习之路,数据结构)