##堆排序
第一步:建堆。在给一个数组的前提下建堆,建大堆而建大堆最重要的就是向下调整。而我自己在尝试堆排序的时候也是在向下调整出的错。#向下调整:1.要判断是不是叶子结点,而堆是一个完全二叉树所以就只用判断有没有左子树。2.接下来判断有没有右子树,并且比较左子树的值和右子树的值的大小。
3.用子树中的较大值和根结点作比较如果大于根的话交换。交换的时候要注意传的是地址。
第二步:排序。当你的大堆已经建好那根结点也就是数组arr[0]的位置就是最大值。1.交换arr[0]和二叉树最后一个结点arr[size-1]这样你就使数组最后一个的成为最大值也就是你想要得到的。2.当交换完后,你需要让size-1这样你就得到一个只有arr[0]不符合的一个大堆,只需要继续向下调整就好了。
代码:
#include<stdio.h>
#include<stdlib.h>
void swap(int *a, int *b){
int t = *a;
*a = *b;
*b = t;
}
void adjustdown(int arr[], int size,int parrent){//向下调整
int left = parrent * 2 + 1;
int right = parrent * 2 + 2;
if (left >= size){
return parrent;
}//判断是不是叶子结点
int max = left;//走到这肯定不是叶子结点,因为它是完全二叉树所以肯定有叶子结点,假设左子树的值为最大值因为不保证它有没有右子树
if (right <= (size-1)&&arr[left]<arr[right]){
max = right;
}//如果有右子树并且它的值大于左子树才会改变max
if (arr[parrent] < arr[max]){
swap(arr+parrent, arr+max);//这里要传的是地址
adjustdown(arr, size, max);
}
}
void creatheap(int arr[], int size){建堆
for (int i = (size - 2) / 2; i >= 0; i–){
adjustdown(arr, size, i);
}
}
void heapsort(int arr[], int size){//堆排序
creatheap(arr, size);
for (int i = 0; i < size; i++){
swap(arr, arr+size-1-i);//将根节点的值和最后一个叶子结点的值交换,并且注意size-1-i
adjustdown(arr, size - 1 - i, 0);//每次向下调整size-1都会再-1
}
}
int main(){
int arr[] = { 4, 3, 8, 9, 6, 5, 7, 6, 4, 2, 0, 1 };
int size = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < size ; i++){
printf("%d", arr[i]);
}
printf("\n");
heapsort(arr, size);
for (int i = 0; i < size ; i++){
printf("%d", arr[i]);
}
system(“pause”);
return 0;
}