一、堆排序简单介绍
1、什么是堆:
堆是一个完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序的平均时间复杂度为Ο(nlogn) .
2、筛选一个节点:
筛选的目的是通过调整节点之间的key值使得以当前结点为根的子树也是一个堆。
3、堆排序的基本过程:
1、从最后一个非叶子节点(当前待排序节点数/2)开始筛选,筛选到第一个节点结束,此时第一个节点就是当前的最值。
2、将当前最值与最后一个节点交换(即取出最值)。当前待排序节点数-1。
3、在已有的堆的基础上筛选第一个节点(因为此时只有第一个节点不符合堆的特性)。
4、重复步骤2、3直到当前带排序节点数减为1。
二、代码实现
</pre><pre name="code" class="cpp">#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define DATA_SIZE 20
int* init_data(int *a, int len);
void free_date(int *a);
void print_data(int *a, int len);
void adjust_heap(int *a, int startidx, int len);
void do_sort(int *a, int len);
void swap(int *a, int i, int j);
int main()
{
int *a;
a = init_data(a, DATA_SIZE);
if (!a)
{
return -1;
}
printf("Before sorting:\n");
print_data(a, DATA_SIZE);
do_sort(a, DATA_SIZE);
printf("After sorting:\n");
print_data(a, DATA_SIZE);
free_date(a);
return 0;
}
int* init_data(int *a, int len)
{
a = (int*)malloc(len*sizeof(int));
if (!a)
{
return NULL;
}
srand(time(NULL));
int i;
for (i = 0 ; i < len ; ++i)
{
a[i] = rand()%100;
}
return a;
}
void print_data(int *a, int len)
{
int i;
for (i = 0 ; i < len ; ++i)
{
printf("%3d", a[i]);
}
printf("\n");
}
void free_date(int *a)
{
free(a);
}
void do_sort(int *a, int len)
{
int first_no_leaf = len/2 - 1;
int i;
for (i = first_no_leaf ; i >= 0 ; --i)
{
adjust_heap(a, i, len - i);
}
for (i = len - 1; i > 0 ; --i)
{
swap(a, 0, i);
adjust_heap(a, 0, i);
}
}
void adjust_heap(int *a, int startidx, int len)
{
int cur_result = startidx;
int tmp = a[cur_result];
while (1)
{
int cur_left = 2*cur_result + 1;
int cur_right = cur_left + 1;
if (cur_right - startidx >= len)
{
if (cur_left - startidx >= len)
{
a[cur_result] = tmp;
break;
}
else
{
if (tmp < a[cur_left])
{
a[cur_result] = a[cur_left];
cur_result = cur_left;
}
else
{
break;
}
}
}
else
{
if (a[cur_left] >= a[cur_right])
{
if (tmp < a[cur_left])
{
a[cur_result] = a[cur_left];
cur_result = cur_left;
}
else
{
break;
}
}
else
{
if (tmp < a[cur_right])
{
a[cur_result] = a[cur_right];
cur_result = cur_right;
}
else
{
break;
}
}
}
}
a[cur_result] = tmp;
}
void swap(int *a, int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}