[算法与数据结构] - No.6 堆排序

首先,什么叫堆呢?

堆 ( Heap )设有一个关键字集合,按完全二叉树的顺序存储方式存放在一个一维数组中。对它们从根开始,自顶向下,同一层自左向右从 1开始连续编号。若满足
           Ki <= K2i && Ki <= K2i+1 
或        Ki >= K2i  && Ki >= K2i+1, 
则称该关键字集合构成一个堆。
前者成为最小堆,后者称为最大堆。通俗来说,小顶堆就是堆顶元素是整个二叉树中最小的。同时每一个子树也都是一个小顶堆。

如何建立堆呢?

首先,对于一个存储在数组中的二叉树(完全二叉树)(下标从0开始),对于任意节点i 其左子下标为2*i+1,右子为2*i+2。将一无序序列看成一个完全二叉树,则最后一个非终端结点是第n/2(求地板)个元素,则从该元素开始自下向上逐步调整为小顶堆。

建堆算法如下(默认是):大顶堆

1. 首先找到最后一个非叶子节点。设最后一个节点的下标是i。那么最后一个非叶子节点的下标是k = (i-1)/2求地板。

2. 然后从下标K元素开始,看下标K元素的左右子是否比下标K大;如果没有访问K-1节点;如果有,选择左右子中最大的节点K1,交换K1和K。由于交换可能破坏了K1为根元素的最大堆,递归访问K1执行2操作直到最大堆建立完成

建堆算法描述

建堆:

int arr [1000];
int n;
void SortHeap(int rootindex,int lastindex)
{
    //cout<<rootindex<<endl;
    int biggerindex = rootindex;
    int lChild = 2*rootindex + 1;
    int rChild = 2*rootindex + 2;
    if(rChild<=lastindex)
    {
        if(arr[lChild]>arr[rootindex]||arr[rChild]>arr[rootindex])
        {
            if(arr[lChild]>arr[rChild])
            {
                biggerindex = lChild;
            }
            else
            {
                biggerindex = rChild;
            }
        }
    }
    else if(lChild<=lastindex)
    {
        if(arr[lChild]>arr[rootindex])
        {
            biggerindex = lChild;
        }
    }

    if(biggerindex!=rootindex)
    {
        int temps = arr[biggerindex];
        arr[biggerindex] = arr[rootindex];
        arr[rootindex] = temps;
        //for(int i = 0 ; i < n; i++)
       // {
           // cout<<arr[i]<<" ";
       // }
        //cout<<endl;
        SortHeap(biggerindex,lastindex);
    }
}
void BuildHeap(int n)
{
    //int lastp = (lastindex-1)/2;
    int lastindex = n-1;
    for(int i=(lastindex-1)/2;i>=0;i--)
    {
        SortHeap(i,lastindex);
    }
}

堆排序

每次选取堆顶元素,将堆顶元素取出。然后将最后的元素放在堆顶,重新建成最大堆。重复n-1次
void HeapSort()
{
    int lastindex = n - 1;
    while(lastindex>0)
    {
        int temps = arr[0];
        arr[0] = arr[lastindex];
        arr[lastindex] = temps;
        lastindex--;
        if(lastindex == 0 )
            break;
        SortHeap(0,lastindex);
    }
}
全部代码

#include <iostream>


using namespace std;
int arr [1000];
int n;
void SortHeap(int rootindex,int lastindex)
{
    //cout<<rootindex<<endl;
    int biggerindex = rootindex;
    int lChild = 2*rootindex + 1;
    int rChild = 2*rootindex + 2;
    if(rChild<=lastindex)
    {
        if(arr[lChild]>arr[rootindex]||arr[rChild]>arr[rootindex])
        {
            if(arr[lChild]>arr[rChild])
            {
                biggerindex = lChild;
            }
            else
            {
                biggerindex = rChild;
            }
        }
    }
    else if(lChild<=lastindex)
    {
        if(arr[lChild]>arr[rootindex])
        {
            biggerindex = lChild;
        }
    }


    if(biggerindex!=rootindex)
    {
        int temps = arr[biggerindex];
        arr[biggerindex] = arr[rootindex];
        arr[rootindex] = temps;
        //for(int i = 0 ; i < n; i++)
       // {
           // cout<<arr[i]<<" ";
       // }
        //cout<<endl;
        SortHeap(biggerindex,lastindex);
    }
}
void BuildHeap(int n)
{
    //int lastp = (lastindex-1)/2;
    int lastindex = n-1;
    for(int i=(lastindex-1)/2;i>=0;i--)
    {
        SortHeap(i,lastindex);
    }
}
void HeapSort()
{
    int lastindex = n - 1;
    while(lastindex>0)
    {
        int temps = arr[0];
        arr[0] = arr[lastindex];
        arr[lastindex] = temps;
        lastindex--;
        if(lastindex == 0 )
            break;
        SortHeap(0,lastindex);
    }
}
int main()
{


    cin >> n;
    for(int i = 0 ; i < n; i++)
    {
        cin>>arr[i];
    }
    BuildHeap(n);
    HeapSort();
    for(int i = 0 ; i < n; i++)
    {
        cout<<arr[i]<<" ";
    }
    return 0;
}







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值