自己在堆排序上的思路和遇见的问题

本文详细介绍了堆排序的两个核心步骤:建堆和排序。通过向下调整算法保持堆的特性,实现从无序数组到有序数组的转换。文章提供了完整的C语言实现代码,包括建堆、向下调整和堆排序函数。

##堆排序
第一步:建堆。在给一个数组的前提下建堆,建大堆而建大堆最重要的就是向下调整。而我自己在尝试堆排序的时候也是在向下调整出的错。#向下调整: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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值