数据结构 排序(一) 堆排序

堆排序

在上一章节里我们完成了堆的实现和基本操作:https://blog.csdn.net/qq_35423154/article/details/104598702
这里就顺带讲一讲堆排序

堆排序是指利用堆这种数据结构所设计的一种排序算法,它是选择排序的一种。通过堆来进行数据选择

时间复杂度: O (N*logN)
空间复杂度: O (1)
稳定性:不稳定

下面来讲一下具体思路
如利用下面这段数据

int arr[] = {46, 74, 53, 14, 26, 36, 86, 65, 27, 34};

首先将它写成堆的形式
在这里插入图片描述
然后利用向下调整算法把他调整为一个大根堆

void AdjustDown(int *arr, int size, int root)
{
	int parent = root;
	int child = parent * 2 + 1;
	
	while(child < size)
	{
		if(child + 1 < size && arr[child] < arr[child + 1])
		{
			++child;
		}
		
		if(arr[child] > arr[parent])
		{
			int temp = arr[parent];
			arr[parent] = arr[child];
			arr[child] = temp;
		}
		else
			break;

		
		parent = child;		
		child = parent * 2 + 1;
	}
}

在这里插入图片描述
这个算法在上一章就讲过了,在这里就不说了。

在这里有一个需要注意的地方,如果要排升序,就要建立大根堆,如果排降序,就要建立小根堆。

按照正常的思路, 排升序应该把小的放在前面,应该建立小根堆,这样的算法不是不行,但是效率太低,因为当我们排完一趟之后,堆的结构就会被完全打乱,我们就需要再次建立一个小根堆,这样的效率是极其低下的。但是我们如果用大根堆,堆顶是最大的数据,我们把他和末尾数字交换,我们就把最大的数据放到最后了,按照这种方法一次将次大数据放到末尾,就完成了排序

这就是堆排序的核心,也就是选择排序的思路,每趟选择一个最大或者最小的元素放到它应该呆的位置上。

同时,使用大根堆还有一个优势,就是交换后堆的结构没有被破坏,只需要一趟向下排序算法就可以再次建立大根堆,这样的效率是非常高的。

void HeapSort(int *arr, int size)
{
	int i = 0;
	for(i = (size - 2) / 2 ; i >= 0; i--)
	{
		AdjustDown(arr, size, i);
	}

	for(i = size - 1; i > 0; i--)
	{		
		int temp = arr[0];
		arr[0] = arr[i];
		arr[i] = temp;
		AdjustDown(arr, i, 0);
	}
}

算法非常简短,首先建立一个大根堆,然后每趟排序堆顶和堆尾进行交换,再用一个向下排序算法恢复大根堆即可实现。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
具体步骤
在这里插入图片描述
完整代码

void AdjustDown(int *arr, int size, int root)
{
	int parent = root;
	int child = parent * 2 + 1;
	
	while(child < size)
	{
		if(child + 1 < size && arr[child] < arr[child + 1])
		{
			++child;
		}
		
		if(arr[child] > arr[parent])
		{
			int temp = arr[parent];
			arr[parent] = arr[child];
			arr[child] = temp;
		}
		else
			break;

		
		parent = child;		
		child = parent * 2 + 1;
	}
}

void HeapSort(int *arr, int size)
{
	int i = 0;
	for(i = (size - 2) / 2 ; i >= 0; i--)
	{
		AdjustDown(arr, size, i);
	}

	for(i = size - 1; i > 0; i--)
	{		
		int temp = arr[0];
		arr[0] = arr[i];
		arr[i] = temp;
		AdjustDown(arr, i, 0);
	}
 
}
发布了60 篇原创文章 · 获赞 78 · 访问量 6322

猜你喜欢

转载自blog.csdn.net/qq_35423154/article/details/104654983
今日推荐