堆排序算法

本文详细介绍了堆排序算法的概念,包括大顶堆和小顶堆的定义,以及如何通过数组映射堆结构。堆排序的过程包括构建大顶堆、交换堆顶元素与末尾元素、调整堆等步骤,时间复杂度为O(nlogn),空间复杂度为O(1)。文中还给出了核心代码实现,便于理解与应用。
摘要由CSDN通过智能技术生成

堆排序

概念:
堆是具有以下性质的完全二叉树:
1.每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;
2.每个结点的值都小于或等于其左  右孩子结点的值,称为小顶堆
同时,我们对堆中的结点按层从左至右进行编号(0,1...),将这种逻辑结构映射到数组中。
     下标为i的节点的父节点下标:(i-1)/2
     下标为i的节点的左孩子下标:i*2+1
     下标为i的节点的右孩子下标:i*2+2
  注意:树中存放的是数组元素的下标。
思路
将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

(1)调整序列使其变成大顶堆:就是从下往上、从右到左,将每个非叶节点当作根节点,将其和子树调整成大顶堆;
   
 (2)堆排序:就是先构建一个堆,用(1)对其调整为大顶堆;
 
 (3)让调整好后的大顶堆的根节点和最后一个节点互换对应的数组中的值,并让最后的节点移走,再从编号为0的树调整序列构成大顶堆;
 
 (4)重复(3)中步骤,直至数的长度小于1;

时间空间复杂度

时间复杂度:O(nlogn)
堆排序分为建堆和调整堆两大块。
建堆是通过父节点和子节点两两比较并交换得到的,时间复杂度为O(n),调整堆需要交换n-1次堆顶元素,并调整堆,调整堆的过程就是满二叉树的深度logn,时间复杂度为O(nlogn),

空间复杂度为O(1)。

核心代码实现

int heap_adjust(int *s,int len,int n)//构成大顶堆,s要排序的数组名,len 数组长度
{
    if(s==NULL||len<0)
    {
        return -1;
    }
    int max=n;
    int lchild=2*n+1int rchild=2*n+2;
    if(s[max]<s[lchild]&&lchild<len)
    {
        max=lchild;
    }
    if(s[max]<s[rchild]&&rchild<len)
    {
        max=rchild;
    }
    if(max!=n)
    {
        swap(&s[max],&s[n]);
        heap_adjust(s,len,max);
    }
    return 0;
}    

int heap_sort(int *s,int len)//堆排序
{
    int i=len/2-1;//树最右边的叶节点的父节点
    for(;i>=0;i--)//从最右端开始比较交换,构成第一次构成大顶堆
    {
        heap_adjust(s,len,i);
    }
    for(i=len-1;i>=0;i--)//交换最大值与树的最右边子节点对应的数组数据,每执行一次,将长度-1,是最大值不再参与运算;之后在调用heap_adjust函数,构成新的大顶堆;
    {
        swap(&s[0].&s[i]);
        heap_adjust(s,i,0);//从树的根开始调整交换,构成新的大顶堆;
    }
    return 0;
}
void swap(int *p,int *q)
{
    int temp;
    temp=*p;
    *p=*q;
    *q=temp;
}
void data_show(int *s,int len)
{
    int i;
    for(i=0;i<len;i++)
    {
        printf("%d ",s[i]);
    }
    printf("\n");
}

运行结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值