堆排序原理:
堆排序指的是将大堆(小堆)堆顶(即下标为0)元素与堆的最后一个(即下标为hp->size - 1)元素交换,hp->size–,将其余的元素再次调整成大堆(小堆),再次将堆顶(即下标为0)元素与堆的最后一个(即下标为hp->size - 1)元素交换,hp->size–,将其余的元素再次调整成大堆(小堆)…………重复上述步骤,直至hp->size<1,将hp->size恢复为原来的值,循环不在继续。
关于升序或者降序应该建立什么堆???
排升序:
若想排升序即最大值应该在最后面,根据堆排序原理,应该建大堆,这样将堆顶元素与最后一个元素交换之后,最大值换到了最后面。
排降序:
若想排降序即最小值应该在最后面,根据堆排序原理,应该建小堆,这样将堆顶元素与最后一个元素交换之后,最小值换到了最后面。
堆的详细概念以及创建等操作
**代码实现: **
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
typedef struct Heap
{
int *data;
int size;
}Heap;
//堆排序
void Heap_Sort(int *array, int size);
//////////////////////////////////////////
void swap(int *x, int *y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
void AdjustHeap(Heap *hp, int parent)
{
int child = 2 * parent + 1;
while (child < hp->size)
{
//找出左右孩子的较大值
if (child + 1 < hp->size&&hp->data[child + 1] > hp->data[child])
{
child = child + 1;
}
//如果孩子中的最大值比父母大,则交换
if (hp->data[child]>hp->data[parent])
{
swap(&hp->data[child], &hp->data[parent]);
parent = child;
child = 2 * parent + 1;
}
else
return;
}
}
//创建堆
void CreatHeap(Heap *hp, int *array, int size)
{
int root = 0;
hp->data = (int *)malloc(size*sizeof(int));
if (hp->data == NULL)
{
return;
}
//先将数组中的元素拷贝至堆中
memcpy(hp->data, array, size*sizeof(int));
//向下调整堆
hp->size = size;
root = (hp->size - 2) / 2;
for (; root >= 0; root--)
{
AdjustHeap(hp, root);
}
}
//排序
void HeapSort(Heap *hp)
{
int size = hp->size;
while (hp->size > 1)
{
swap(&hp->data[0], &hp->data[hp->size - 1]);
hp->size--;
AdjustHeap(hp, 0);
}
hp->size = size;
}
//堆排序
void Heap_Sort(int *array, int size)
{
Heap hp;
//创建堆
CreatHeap(&hp, array, size);
//排序
HeapSort(&hp);
memcpy(array,hp.data, size*sizeof(int));
}
测试文件:
#include"sort.h"
void TestHeapSort()
{
int array[] = { 10, 2, 5, 4, 6, 9, 3, 1, 0 };
printf("排序前:");
//打印
Print(array, sizeof(array) / sizeof(array[0]));
//堆排序
Heap_Sort(array, sizeof(array) / sizeof(array[0]));
printf("排序后:");
//打印
Print(array, sizeof(array) / sizeof(array[0]));
}
int main()
{
TestHeapSort();
system("pause");
return 0;
}
时间复杂度: O(nlogn)
空间复杂度: O(1)
稳定性: 不稳定