堆排序
1.这里讲的是最大堆,最小堆只是找的是最小元素,过程都是一样的。堆的数据是存储在一维数组中的。
2.算法起始第一步需要对未初始化的数组数据进行堆的初始化。
3.堆的初始化就是把最大的元素换到数组的起始位置上。
4.然后把堆的第一个元素与最后一个元素进行互换,并把数组的长度减一,然后对数组的起始元素进行堆调整,重新形成最大堆。
5.直到数组长度等于1.
6.这里需要注意,此算法是将数组的其实位置也就是0位置空余出来的,从位置1开始。
2.算法起始第一步需要对未初始化的数组数据进行堆的初始化。
3.堆的初始化就是把最大的元素换到数组的起始位置上。
4.然后把堆的第一个元素与最后一个元素进行互换,并把数组的长度减一,然后对数组的起始元素进行堆调整,重新形成最大堆。
5.直到数组长度等于1.
6.这里需要注意,此算法是将数组的其实位置也就是0位置空余出来的,从位置1开始。
7.以下就是c语言实现的代码:
//获得元素的父节点
#define num 10
typedef struct{
int arr[num];
int heap_capacity;
int heap_size;
}node;
int parent(int i){
return i / 2;
}
//获得元素的左结点
int left(int i){
return i * 2;
}
//获得元素的右结点
int right(int i){
return i * 2 + 1;
}
//调整最大堆。---因为堆排序的调整方向是从父节点往下调整的。
//所以叶子节点就不需要调整了。
void max_heapify(node *array, int i){
int l = left(i);
int r = right(i);
int larger;
if (l < (*array).heap_size && (*array).arr[l] >(*array).arr[i]){//左孩子先与父节点比较
larger = l;
}else{
larger = i;
}
if (r <= (*array).heap_size && (*array).arr[r] > (*array).arr[larger]){//右孩子与大的比较
larger = r;
}
if (larger != i){//如果发生替换则继续向下调整
int temp = (*array).arr[larger];
(*array).arr[larger] = (*array).arr[i];
(*array).arr[i] = temp;
max_heapify(array, larger);
}
}
void build_max_heap(node *array){
for (int i = ((*array).heap_size ) / 2; i > 0; i--){//数组下标的调整,数组下标是从0开始的。
max_heapify(array, i);
}
}
void heap_sort(node *array){
build_max_heap(array);
//建立最大堆之后,最大的元素在数组的第一个位置上
//然后将它与数组的最后一个元素互换,并size-1
//再重新初始化最大堆,因为第一个位置的元素发生了改变,所以对第一个位置的元素
//进行最大堆的初始化
for (int i = (*array).heap_size; i > 1; i--){
int temp = (*array).arr[i];
(*array).arr[i] = (*array).arr[1];
(*array).arr[1] = temp;
(*array).heap_size--;
max_heapify(array, 1);
}
}
int main(){
//int arr2[10];
node array;
int i = 1;
array.heap_size = array.heap_capacity = num;
printf("input %d nums:\n", num-1);
while (i<num){
scanf("%d", &array.arr[i]);
i++;
}
heap_sort(&array);
printf("the result is : \n");
for (int i = 1; i < array.heap_capacity; i++){
printf("%d ", array.arr[i]);
}
}