C语言堆排序

本文介绍了使用C语言实现堆排序的详细步骤。通过构造大顶堆,将根节点与尾节点交换并输出,逐步构建有序序列。该算法的时间复杂度为O(nlogn),空间复杂度为O(1)。配合图解流程,帮助理解堆排序的过程。
摘要由CSDN通过智能技术生成

算法思想(以大顶堆为例):

1.将长度为n的待排序的数组进行堆有序化构造成一个大顶堆

2.将根节点与尾节点交换并输出此时的尾节点

3.将剩余的n -1个节点重新进行堆有序化

4.重复步骤2,步骤3直至构造成一个有序序列

#include<stdio.h>

void Swap(int* arr,int i,int j){
    int temp=arr[i];
    arr[i]=arr[j];
    arr[j]=temp;
}

//构造大根堆(通过新插入的数上升)
void HeapInsert(int* arr,int length){
    int i;
    for(i=0;i<length;i++){
        int currentIndex=i; //当前插入的索引
        int fatherIndex=(currentIndex-1)/2; //父结点索引
        //如果当前插入的值大于其父结点的值,则交换值,并且将索引指向父结点
        //然后继续和上面的父结点值比较,直到不大于父结点,则退出循环
        while(arr[currentIndex]>arr[fatherIndex]){
            Swap(arr,currentIndex,fatherIndex);//交换当前结点与父结点的值)
            currentIndex=fatherIndex; //将当前索引指向父索引
            fatherIndex=(currentIndex-1)/2;//重新计算当前索引的父索引
        }
    }
}

//将剩余的数构造成大根堆(通过顶端的数下降)
void Heapify(int* arr,int index,int size){
    int left=index*2+1;
    int right=index*2+2;
    while(left<size){
        int largestIndex;
        //判断孩子中较大的值的索引(要确保右孩子在size范围之内)
        if(arr[left]<arr[right]&&right<size){
            largestIndex=right;
        }else{
            largestIndex=left;
        }
        //比较父结点的值与孩子中较大的值,并确定最大值的索引
        if(arr[index]>arr[largestIndex]){
            largestIndex=index;
        }
        //如果父结点索引是最大值的索引,那已经是大根堆了,则退出循环
        if(index==largestIndex){
            break;
        }
        //父结点不是最大值,与孩子中较大的值交换
        Swap(arr,largestIndex,index);
        //将索引指向孩子中较大的值的索引
        index=largestIndex;
        //重新计算交换之后的孩子的索引
        left=index*2+1;
        right=index*2+2;
    }
}

//堆排序
void HeapSort(int* arr,int length){
    HeapInsert(arr,length);//构造大根堆
    while(length>0){
        Swap(arr,0,length-1); //固定最大值
        length--;
        Heapify(arr,0,length); //构造大根堆
    }
}

void PrintArr(int* arr, int length){
    int i;
	for ( i = 0; i < length; i++){
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main(){
    int a[10]={5,1,9,3,7,4,8,6,2,0};
    int length = sizeof(a)/sizeof(a[0]);
    HeapSort(a,length);
    PrintArr(a,length);
    return 0;
}

时间复杂度:O(nlogn)

空间复杂度:O(1)

图解流程:https://blog.csdn.net/u010452388/article/details/81283998

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值