堆排序(Heapsort)是指利用这种数据结构所设计的一种排序算法,它是选择排序的一种。
可以利用数组的特点快速定位索引的元素。
选择排序的原理:
第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的期初位置,然后再从剩余的未排序元素中找到最小(或最大)元素,然后放到已排序的序列的末尾。依次类推,知道全部待排序的数据元素的个数为零。
排序(最大堆实现从小到大排序,最小堆反之):
将最大堆的初始化,在之前实现的初始化基础上稍微改一下。将原本是数据赋值给堆的,改为堆指向数组。
在实现堆排序时:
1.将堆头(heap.arr[0])与堆尾(heap.arr[heap.size-1])元素互换
2.将堆的大小减一(heap.size–)
3.下调(adjustDown)修改后的堆头(heap.arr[0])
#include <stdio.h>
#include <stdlib.h>
typedef struct _Heap
{
int* arr;
int size;
int capacity;
}Heap;
//初始化堆,实际是将堆指向数组,并非赋值
bool initHeap(Heap& heap, int* origrinal, int size);
static void buildHeap(Heap& heap);
static void adjustDown(Heap& heap, int index);
//堆排序
void heapSort(Heap& heap);
bool initHeap(Heap& heap, int *origrinal, int size)
{
if (size < 1) return false;
heap.arr = origrinal;
if (!heap.arr) return false;
heap.capacity = size;
heap.size = size;
buildHeap(heap);
return true;
}
void buildHeap(Heap& heap)
{
for (int i = heap.size / 2 - 1; i >= 0; i--)
{
adjustDown(heap, i);
}
}
void adjustDown(Heap& heap, int index)
{
int cur = heap.arr[index];
int parent, child;
for (parent = index; parent * 2 + 1 < heap.size; parent = child)
{
child = parent * 2 + 1;
if (child + 1 < heap.size && heap.arr[child] < heap.arr[child + 1])
{
child++;
}
if (heap.arr[child]>heap.arr[parent])
{
heap.arr[parent] = heap.arr[child];
heap.arr[child] = cur;
}
else
{
break;
}
}
}
void heapSort(Heap& heap)
{
if (heap.size < 1) return;
while (heap.size > 0)
{
//1,换位置,将最大元素堆头,换到堆尾
int tmp = heap.arr[0];
heap.arr[0] = heap.arr[heap.size - 1];
heap.arr[heap.size - 1] = tmp;
//2,将堆的可控大小减一
//此时,之前被换下来的堆头还在数组中,在数组尾部
//而不再在,堆中了
heap.size--;
//3,刚从堆尾换上来的堆首下调
adjustDown(heap,0);
}
}
int main()
{
Heap heap;
int origrinal[] = { 35,2,55,78,89,46 };
printf("原始数组:\n");
for (int i = 0; i < sizeof(origrinal) / sizeof(int); i++)
{
printf("%d,", origrinal[i]);
}
printf("\n\n");
initHeap(heap, origrinal, sizeof(origrinal)/sizeof(int));
printf("初始化最大堆后的数组:\n");
for (int i = 0; i < sizeof(origrinal) / sizeof(int); i++)
{
printf("%d,", origrinal[i]);
}
printf("\n\n");
printf("堆排序后的数组:\n");
heapSort(heap);
for (int i = 0; i < sizeof(origrinal) / sizeof(int); i++)
{
printf("%d,", origrinal[i]);
}
printf("\n\n");
system("pause");
return 0;
}