关于堆排序的原理请各位自行了解,本文章主要叙述如何通过c语言代码实现堆排序。
请了解一下名词:
1.堆
2.大顶堆
3.小顶堆
大顶堆用于增序排列
小顶堆用于降序排列
简言之:若我的下标为n,则我的父节点下标为(n-1)/2,我的左子节点下标为2*n+1,我的右子节点下标为2*n+2
堆排序过程(升序):
1.构建大顶堆(根节点是最大的)
2.将第一个元素与最后一个元素交换(将最大的放到最后)
3.需要排序的数组长度减1(将刚才最大的那个排除在外)
4.重复过程1,2,3直至需要排序的数组长度为1
5.整体过程相当于每进行一次"大根堆"的建立,最大的元素就会"浮"到最前面去,将它换到最后面后,把他排除在这个"堆"之外,也就是下一次进行大根堆的建立的时候不带上他了。然后每一次就把目前的堆中最大的往后面填,直到这个堆的长度只有1,那么排序就完成了
#include<stdio.h>
//交换两个元素的值
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
// 将dad节点下面的都调整为大根堆
void heapify(int *arr, int dad, int end)
{
int son = 2 * dad + 1;
while (son <= end)
{
if (arr[son] < arr[son + 1] && son + 1 <= end)
son++;
if (arr[son] > arr[dad])
{
swap(&arr[son],&arr[dad]);
dad=son;
son=2*dad+1;
}
else
{
break;
}
}
}
void heap_sort(int *arr, int len)
{
// 4.循环步骤1,2,3直至,需要排序的数组长度为1
while (len>1)//len是需要排序的个数,取值是1,2,3...
{
int end=len-1; //end保存最后一个元素的下标
int dad=0; //dad是倒数第二层最后一个父节点
//将数组大根堆化
for (dad = (len - 2) / 2; dad >= 0; dad--)
heapify(arr, dad, end );
// 2.将堆顶元素与末尾元素交换
swap(&arr[0],&arr[end]);
// 3.需要排序的数组长度-1
len--;
}
}
int main()
{
int i = 0;
int arr[10] = { 2, 4, 3, 1, 8, 5, 0, 9, 7, 6 };
int len = sizeof(arr) / sizeof(arr[0]);
// sort
heap_sort(arr, len);
// 打印数组
for (i = 0; i < len; i++)
printf("%d ", arr[i]);
return 0;
}