前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >堆排序

堆排序

作者头像
AI那点小事
发布2020-04-20 15:21:08
3920
发布2020-04-20 15:21:08
举报
文章被收录于专栏:AI那点小事AI那点小事

概述

堆排序是利用堆的特性——堆顶元素一定是这个堆的最大值或者最小值,来使选择排序中每趟选择最值变得更加高效的思路。对于堆的相关内容移步我之前的博客:


算法思想

这里我们默认从小到大排序。 思路一:首先把通过数组构造一个最小堆,之后依次执行最小堆的删除操作直至最小堆为空则能得到一个从小到大的序列。对于时间复杂度一定是O(nlogn)。然而这个算法却带来了O(n)的空间复杂度。那么这显然是不划算的。故这就有了思路二。 思路二:首先通过n个数的数组构造一个最大堆,这是执行如下操作:把堆中最后一个元素(下标为n-1)与第一个元素(下标为0)互换位置,之后把0至n-2的数组调整为最大对,重复上述操作直至只剩一个元素。这样就避免了O(n)的空间复杂度。


全部代码

代码语言:javascript
复制
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

const int MAX = 65535;

class HeapSort{
    private:
        int* data;
        int size;
    public:
        //构造函数
        HeapSort(int* data,int len){
            this->size = 0;
            this->data = new int[len+1];
            this->data[0] = MAX;
            for(int i = 0 ; i < len ; i++){
                this->data[++this->size] = data[i];
            }
            this->BuildHeap();
        }

        //把下标为n的子树调整为最大堆
        void Predown(int start ,int end){
            int parent ,child;
            int x = this->data[start];
            for(parent = start ; 2*parent < end ; parent = child){
                child = parent*2;
                //child+1不是最后一个元素,且右孩子大于左孩子 
                if(child+1 != this->size && this->data[child+1] > this->data[child]){
                    child++; 
                }
                if(x >= this->data[child]){
                    break;
                }else{
                    this->data[parent] = this->data[child];
                } 
            }
            this->data[parent] = x;
        } 

        //建堆函数
        void BuildHeap(){
            for(int i = this->size/2 ; i >= 0 ; i--){
                this->Predown(i,this->size);
            }
        }

        void Swap(int* a,int* b){
            *a = *a + *b;
            *b = *a - *b;
            *a = *a - *b; 
        } 

        //堆排序
        void Heap_Sort(){
            for(int i = this->size ; i > 0 ; i--){
                //交换最后一个与第0个元素 
                this->Swap(&this->data[0],&this->data[i]);
                //把0到i-1个数调整为最大堆 
                this->Predown(0,i-1);
            }
        }

        void Print(int start , int end){
            for(int i = start ; i <= end; i++){
                cout<<this->data[i]<<" ";
            }
            cout<<endl;
        } 
};

int main()
{
    cout<<"请输入数组长度:"<<endl;
    int size,*data;
    cin>>size;
    data = new int[size]; 
    srand(time(0));
    cout<<"随机初始化"<<size<<"个数"<<endl;
    for(int i = 0 ; i < size ; i++){
        data[i] = rand()%100+1;
    }

    HeapSort sort(data,size);
    cout<<"堆排序前:"<<endl;
    sort.Print(1,size);
    cout<<"堆排序后:"<<endl;
    sort.Heap_Sort();
    sort.Print(0,size-1); 

    return 0;
 } 

截图:

这里写图片描述
这里写图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 算法思想
  • 全部代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档