堆排序-代码版

Posted WayToAccept

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆排序-代码版相关的知识,希望对你有一定的参考价值。

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

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

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

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

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

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




以上是关于堆排序-代码版的主要内容,如果未能解决你的问题,请参考以下文章

堆排序及java版实现

希尔排序 堆排序 归并排序

堆排序(C++版)

10-9-堆排序-内部排序-第10章-《数据结构》课本源码-严蔚敏吴伟民版

[数据结构学习备忘录]堆及其堆排序

数据结构:堆排序(python版)