堆排序(heap sort),像合并排序二不像插入顺序,堆排序的运行时间为O(nlgn)。像插入排序而不像合并排序,它是一种原地(in place)排序算法:在任何时候,数组中只有常数个元素存储在输入数组以外。结合了插入排序和合并排序的优点。
堆排序还引入另一种算法设计技术:利用某种数据结构(在此算法中为”堆“)来管理算法执行中的信息。堆数据结构不只是在堆排序中有用,还可以构成一个有效的优先队列。
有三个过程:
1、max_heapify过程,其运行时间为O(lgn),是保持最大堆性质的关键。
2、build_max_heap过程,以线性时间运行,可以在无序的输入数组基础上构造出最大堆。
3、heapsort过程,运行时间为O(nlgn),对一个数组原地进行排序。
学习实现代码:
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
void print_array(int *, const int);
int parent(int);
int left(int);
int right(int);
int exchange(int *, int, int);
void max_heapify(int *, int, const int);
void build_max_heap(int *, const int);
void heap_sort(int *, const int);
int main(void)
{
int a[ARRAY_SIZE] = {16, 4, 10, 14, 7, 9, 3, 2, 8, 1};
//max_heapify(a, 1, ARRAY_SIZE);
//build_max_heap(a, ARRAY_SIZE);
heap_sort(a, ARRAY_SIZE);
print_array(a, ARRAY_SIZE);
}
void print_array(int * a, const int size)
{
int i = 0;
for(; i < size; i++)
printf("%d ", a[i]);
putchar('\n');
}
int parent(int i)
{
return (i - 1) >> 1;
}
int left(int i)
{
return (i << 1) + 1;
}
int right(int i)
{
return (i << 1) + 2;
}
int exchange(int * a, int i, int j)
{
if(i != j)
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
void max_heapify(int * a, int i, const int heap_size)
{
int left_index = left(i), right_index = right(i), largest = 0;
if(left_index < heap_size && a[left_index] > a[i])
{
largest = left_index;
}
else
{
largest = i;
}
if(right_index < heap_size && a[right_index] > a[largest])
{
largest = right_index;
}
if(largest != i)
{
exchange(a, i, largest);
max_heapify(a, largest, heap_size);
}
}
void build_max_heap(int * a, const int heap_size)
{
int i = (heap_size >> 1) - 1;
for(; i >= 0; i--)
{
max_heapify(a, i, heap_size);
}
}
void heap_sort(int * a, const int heap_size)
{
build_max_heap(a, heap_size);
int i = heap_size - 1;
int temp_heap_size = heap_size;
for(; i >= 1; i--)
{
exchange(a, 0, i);
temp_heap_size = temp_heap_size - 1;
max_heapify(a, 0, temp_heap_size);
}
}