(三)堆排序

/*******************************************
堆排序,时间复杂度O(nlgn)
伪代码:
1.下标计算[为与程序对应,下标从0开始]
Parent(i):
    return i/2
Left(i):
    return 2*i+1
Right(i):
    return 2*i+2
2.使下标i元素为根的的子树成为最大堆
MAX_HEAPIFY(A,i):
l<——Left(i)
r<——Right(i)
if l<length(A) and A[l]>A[i]
    then largest<——l
    else largest<——i
if r<length(A) and A[r]>A[largest]
    then largest<——r
if largest != i
    then exchange A[i] <——> A[largest]
    MAX_HEAPIFY(A,largest)
3.最大堆的建立,将数组A编译成一个最大堆
BUILD_MAX_HEAP(A):
    heapsize[A]<——length[A]
for i <—— length[A]/2+1  to 0
    MAX_HEAPIFY(A,i)
4.堆排序
HEAP_SORT(A):
    BUILD_MAX_HEAP(A)
    for i<——length[A]-1 to 1
        do exchange A[1] <——>  A[i]
        length[A]<—— length[A]-1
        MAX_HEAPIFY(A,0)
********************************************/
#include <stdio.h>
#include <stdlib.h>
#define PARENT(i) (i)/2
#define LEFT(i) 2*(i)+1
#define RIGHT(i) 2*(i+1)
void max_heapify(int *arr,int index,int len)
{
    int l=LEFT(index);
    int r=RIGHT(index);
    int largest;
    if(l<len && arr[l]>arr[index])
        largest=l;
    else
        largest=index;
    if(r<len && arr[r]>arr[largest])
        largest=r;
    if(largest != index){//将最大元素提升,并递归
        int tmp=arr[largest];
        arr[largest]=arr[index];
        arr[index]=tmp;
        max_heapify(arr,largest,len);
    }
}

void build_maxheap(int *arr,int len)
{
    if(arr==NULL || len<=1)
        return;
    int i;
    for(i=len/2+1;i>=0;--i)
        max_heapify(arr,i,len);
}
void heap_sort(int *arr,int len)
{
    if(arr==NULL || len<=1)
        return;
    int length=len;
    build_maxheap(arr,length);
    int i;
    int tmp;
    for(i=length-1;i>=1;--i){
        tmp=arr[0];
        arr[0]=arr[i];
        arr[i]=tmp;
        max_heapify(arr,0,--length);
    }
}
//test 
int main()
{
    int arr[10]={1,4,6,2,5,8,7,6,9,12};
    heap_sort(arr,10);
    int i;
    for(i=0;i<10;++i)
        printf("%d ",arr[i]);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值