您的位置:首页 > 其它

堆排序

2013-09-15 00:04 183 查看

《算法导论》第六章----堆排序

堆数据结构是一种数组对象,它可以被视为一棵完全二叉树。

堆排序
#include <stdio.h>
#include <stdlib.h>

/*
int parent(int i); //返回父节点下标

int left(int i); //返回左儿子节点下标

int right(int i); //返回右儿子节点下标
*/

void max_heapify(int A[], int length, int i); //保持堆的性质

void build_max_heap(int A[], int length); //在输入数组基础上构造出最大堆

void heap_sort(int A[], int length); //对一个数组原地进行排序

int main(){
int num, i;
printf("Input the number:\n");
scanf("%d", &num);
int *array = malloc((num + 1) * sizeof(int));
printf("Input the element:");
for(i = 1; i <= num; i++)
scanf("%d", &array[i]);

heap_sort(array, num);

for(i = 1; i <= num; i++)
printf("%d ", array[i]);
printf("\n");
return 0;
}

/*
*这个函数是维持堆的性质,注意当调用这个函数的时候,我们假定该节点的左右儿子树都是最大堆。
*但是有可能该节点小于它的子树,所以通过这个函数使该节点下降,使以该节点为根的子树成为最大堆。
*/
void max_heapify(int A[], int length, int i){
int l = 2 * i; //左儿子节点下标
int r = 2 * i + 1; //右儿子节点下标
int largest; //记录该节点与左右儿子节点中值最大的下标

if(l <= length && A[l] > A[i])
largest = l;
else
largest = i;

if(r <= length && A[r] > A[largest])
largest = r;

if(largest != i){
int temp = A[largest];
A[largest] = A[i];
A[i] = temp;
max_heapify(A, length, largest);
}
}

/*
*练习6.3-2:为什么从下标floor(length/2)降到1,而不是从1升到floor(legnth/2)?
*max_heapify函数假设左右儿子为根的二叉树都为最大堆,如果从1开始的话,其左右儿子为根的二叉树不一定为最大堆。
*而从floor(length/2)开始则可以保证左右儿子为根的二叉树都是最大堆
*/
void build_max_heap(int A[], int length){
int i;
for(i = length/2; i >= 1; i--)
max_heapify(A, length, i); //调用维持最大堆的性质函数
}

/*
*数组A[1...n]的最大元素为A[1],通过与A
交换达到最终正确的位置。原来根的子女依然是最大堆,
*但是新的根元素可能违背最大堆的性质。因此要调用维持最大堆性质的函数
*然后在A[1...n-1]里重复这个过程。
*/
void heap_sort(int A[], int length){
int i;
int size = length;

build_max_heap(A, length); //建堆
for(i = length; i >= 2; i--){
int temp = A[i];
A[i] = A[1];
A[1] = temp; //交换,将最大的元素放到数组的还没排序的尾部。

size--;
max_heapify(A, size, 1); //调用维持最大堆的性质的函数(此时根节点的左右儿子子树为最大堆)
}
}

堆排序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: