Loading

数据结构排序算法之堆排序

文章目录


代码实现

#include<iostream>

using namespace std;
typedef int elemtype;
//堆排序
void HeapSort(int arr[], int n);
void heapInsert(int arr[], int n);
void heapifl(int arr[], int index, int size);
//int main()
//{
//	//elemtype arr[10] = { 2,4,6,1,3,5,10,9,8,7 };
//	elemtype arr[8] = { 4,2,5,7,3,1,8,6 };
//	HeapSort(arr,8);
//	for (int i = 0; i < 8; i++)
//	{
//		cout << arr[i] << " ";
//	}
//
//	return 0;
//}
//堆排序
//建一个大根堆
void heapInsert(int arr[], int n)		//对堆节点进行插入调整成一个大根堆(有需要的话调整成小根堆也可)
{
	for (int i = n / 2; i >= 0; i--)	//从中间的节点开始调整,因为从中间节点到根节点的每一个节点
	{									//都存在两个子节点,都符合一个堆的性质,所以慢慢进行堆调整
		heapifl(arr, i, n);
	}
}
//调整堆
void heapifl(int arr[], int index, int size)
{
	int left = index * 2 + 1;				//index是父节点,由完全二叉树性质知左节点为2*index+1
	int right = index * 2 + 2;				//右节点是2*index+2
	while (left < size)						//完全二叉树中的节点如果有右节点,那就必然会有左节点,而有左节点却不
	{										//一定有右节点,因此要判断左节点的下标是否到达了最大元素的下标size-1
											//对右节点只需要在比较时单独判断即可
		int largeIndex;						//每次比较都是先比较左右节点中的最大节点,然后获得最大节点下标
		if ( right < size && arr[left] < arr[right] )//在这里比较时要注意右节点有没有超过size-1
			largeIndex = right;
		else
			largeIndex = left;
		if (arr[largeIndex] < arr[index])	//然后比较父节点和最大节点的值
		{
			break;							//如果父节点更大就不用继续往下比较了,因为这三个元素形成的小堆已经符合堆的性质
		}									//直接break退出即可
		swap(arr[index], arr[largeIndex]);	//如果父节点要小于最大的子节点,那就进行交换位置
		index = largeIndex;					//然后父节点来到刚刚更大那个节点的位置
		left = index * 2 + 1;				//同时对新的左右节点进行更新
		right = index * 2 + 2;
	}

}
void HeapSort(int arr[], int n)
{
	
	heapInsert(arr, n);						//建大根堆
	for (int i = n; i > 1;)					//建完大根堆后堆顶元素就是最大值
	{
		swap(arr[0], arr[i - 1]);			//交换堆顶和堆没有固定的那个元素
		i--;								//i--后,最后一个元素就已经被固定了,在后续的堆调整中不会再涉及
		heapifl(arr, 0, i);					//从根节点开始,对没有被固定的堆元素进行堆调整0
	}
}

posted @   墨鱼yyyl  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示