数据结构排序算法之堆排序
文章目录
代码实现
#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
}
}
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术