堆排序-代码版

要说堆排序,首先明白什么是堆:

数据结构与算法中的堆是指,一个特殊的满二叉树,对于每个非叶子结点,它总是比它的子节点大(或者小)

如果每个节点总是大于其子节点,则称为大根堆

如果每个节点总是小于其子节点,则称为小根堆

大根堆用于从小到大排序(每次选最大),小根堆用于从大到小排序(每次选最小)。

堆因为是满二叉树,所以使用数组存储很方便,假定从a[1]的地方开始存储,第i个节点,其左右孩子(假如存在)分别为a[2*i]   a[2*i+1]

堆排序的过程分为两步:

1 从最后一个非叶节点开始,将无序数组调整为堆(大根堆或者小根堆)

2 堆顶元素与最后一个无序元素交换,从堆顶开始继续调整为堆


每次调整过程:

如果当前节点不满足a[i]>a[2*i]&&a[i]>a[2*i+1](或者a[i]<a[2*i]&&a[i]<a[2*i+1]小根堆),则进行交换,然后递归调整。

代码如下

大根堆

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
//调整堆,下标从0开始,左右孩子2*i+1,2*i+2
void AdjHeap1(int a[],int i,int len)
{
    int left=2*i+1,right=2*i+2;
    int max=i;
    if(left<len&&a[left]>a[max])
    {
        max=left;
    }
    if(right<len&&a[right]>a[max])
    {
        max=right;
    }
    if(max!=i)
    {
        int temp=a[i];
        a[i]=a[max];
        a[max]=temp;
        AdjHeap1(a,max,len);
    }
}
void Heap1(int a[],int len)
{
    //构建堆
    for(int i=(len-1)/2;i>=0;--i)
    {
        AdjHeap1(a,i,len);
    }
    for(int i=len-1;i>0;--i)
    {
        int temp=a[0];
        a[0]=a[i];
        a[i]=temp;
        AdjHeap1(a,0,i);
    }
}
//调整堆,下标从1开始,len为元素数+1,左右孩子2*i,2*i+1
void AdjHeap2(int a[],int i,int len)
{
    int left=2*i,right=2*i+1;
    int max=i;
    if(left<len&&a[left]>a[max])
    {
        max=left;
    }
    if(right<len&&a[right]>a[max])
    {
        max=right;
    }
    if(max!=i)
    {
        int temp=a[i];
        a[i]=a[max];
        a[max]=temp;
        AdjHeap2(a,max,len);
    }
}

void Heap2(int a[],int len)
{
    //构建堆
    for(int i=(len-1)/2;i>=1;--i)
    {
        AdjHeap2(a,i,len);
    }
    for(int i=len-1;i>1;--i)
    {
        int temp=a[1];
        a[1]=a[i];
        a[i]=temp;
        AdjHeap2(a,1,i);
    }
}
int main()
{
    int a[20]={0};
    int n;
    while(cin>>n)
    {
        for(int i=0;i<n;++i)
        {
            cin>>a[i];
        }
        Heap1(a,n);

        for(int i=0;i<n;++i)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}


小根堆


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
//调整堆,下标从0开始,左右孩子2*i+1,2*i+2
void AdjHeap1(int a[],int i,int len)
{
    int left=2*i+1,right=2*i+2;
    int min=i;
    if(left<len&&a[left]<a[min])
    {
        min=left;
    }
    if(right<len&&a[right]<a[min])
    {
        min=right;
    }
    if(min!=i)
    {
        int temp=a[i];
        a[i]=a[min];
        a[min]=temp;
        AdjHeap1(a,min,len);
    }
}
void Heap1(int a[],int len)
{
    //构建堆
    for(int i=(len-1)/2;i>=0;--i)
    {
        AdjHeap1(a,i,len);
    }
    for(int i=len-1;i>0;--i)
    {
        int temp=a[0];
        a[0]=a[i];
        a[i]=temp;
        AdjHeap1(a,0,i);
    }
}
//调整堆,下标从1开始,len为元素数+1,左右孩子2*i,2*i+1
void AdjHeap2(int a[],int i,int len)
{
    int left=2*i,right=2*i+1;
    int min=i;
    if(left<len&&a[left]<a[min])
    {
        min=left;
    }
    if(right<len&&a[right]<a[min])
    {
        min=right;
    }
    if(min!=i)
    {
        int temp=a[i];
        a[i]=a[min];
        a[min]=temp;
        AdjHeap2(a,min,len);
    }
}

void Heap2(int a[],int len)
{
    //构建堆
    for(int i=(len-1)/2;i>=1;--i)
    {
        AdjHeap2(a,i,len);
    }
    for(int i=len-1;i>1;--i)
    {
        int temp=a[1];
        a[1]=a[i];
        a[i]=temp;
        AdjHeap2(a,1,i);
    }
}
int main()
{
    int a[20]={0};
    int n;
    while(cin>>n)
    {
        for(int i=1;i<=n;++i)
        {
            cin>>a[i];
        }
        Heap2(a,n+1);
        for(int i=1;i<=n;++i)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值