堆排序-代码版

来源:互联网 发布:什么咖啡最提神知乎 编辑:程序博客网 时间:2024/05/29 11:55

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

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

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

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

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

堆因为是满二叉树,所以使用数组存储很方便,假定从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+2void 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+1void 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+2void 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+1void 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;}



原创粉丝点击