zoukankan      html  css  js  c++  java
  • 大顶堆基本操作(插入,出堆),堆排序(普通,Heapify方式,数组原地堆排序)

    #include<iostream>
    #include<algorithm>
    #include<cassert>
    using namespace std;
    
    //大顶堆  根节点为1,左孩子为2i 右孩子为2i+1
    //对于每一个孩子的父亲为i/2
    class MaxHeap
    {
    
    private:
        int* data;
        int count;
        int capacity;
    
        void shiftUp(int k)
        {
    
            while( k>1 && data[k/2]<data[k])//控制边界,当k=1时就不需要再比了
            {
                swap( data[k/2], data[k]);
                k/=2;
            }
        }
    
        void shiftDown(int k)
        {
    
            while(2*k <=count)
            {
                int j=2*k;//此轮循环中,data[j]和data[k]交换
                if(j+1<=count &&data[j+1]>data[j])//如果有右孩子且比左孩子大
                {
                    j+=1;
                }
                if(data[k]>=data[j])
                    break;
    
                swap(data[k],data[j]);
                k=j;
            }
        }
    public:
        MaxHeap(int capacity)
        {
            data=new int[capacity+1];
            count=0;
            this->capacity= capacity;
        }
    
        MaxHeap(int arr[],int n)//heapify  将一个数组中的元素构造成堆
        //不需要再一个一个的插入操作
        {
            data=new int[n+1];
            capacity=n;
            for(int i=0;i<n;i++)
            {
                data[i+1]=arr[i];
            }
            count=n;
            for(int i=count/2;i>=1;i--)//从第一个不是叶子结点开始
            {
                shiftDown(i);
            }
        }
    
        ~MaxHeap()
        {
            delete []data;
        }
        int size()
        {
            return count;
        }
        bool isEmpty()
        {
            return count==0;
        }
        void insert(int item)
        {
            assert(count+1 <= capacity);
            data[count+1]=item;
            count++;
            shiftUp( count );
        }
        int  extractMax()
        {
    
            assert(count>0);
            int ret=data[1];
            swap(data[1],data[count]);
            count--;
            shiftDown(1);
            return ret;
        }
    };
    
    void  heapSort1(int arr[],int n)
    {
    
        MaxHeap maxheap=MaxHeap(n);
        for(int i=0;i<n;i++)//逐个插入的算法复杂度是nlogn
        {
            maxheap.insert(arr[i]);
        }
        for(int i=n-1;i>=0;i--)
        {
            arr[i]=maxheap.extractMax();
        }
    }
    void heapSort2(int arr[],int n)
    {
        MaxHeap maxheap=MaxHeap(arr,n);//heapify的算法复杂度是n
        for(int i=n-1;i>=0;i--)
        {
            arr[i]=maxheap.extractMax();
        }
    }
    //heapify 最后一个除以2得到的序号就是第一个不是叶子结点的序号
    void __shiftDown(int arr[],int n,int k)
    {
      //现在是从0开始了, 左孩子为2*k+1
         while(2*k+1 < n)
            {
                int j=2*k+1;//此轮循环中,data[j]和data[k]交换
                if(j+1<n && arr[j+1]>arr[j])//如果有右孩子且比左孩子大
                {
                    j+=1;
                }
                if(arr[k]>=arr[j])
                    break;
    
                swap(arr[k],arr[j]);
                k=j;
            }
    }
    //原地堆排序
    void heapSort(int arr[],int n)//在原数组上进行排序 不需要另外再开一个空间
    {
        for(int i=(n-1)/2;i>=0;i--)//heapify    先进行一次heapify  当然现在数组是以0为下标开始的
        {
            __shiftDown(arr,n,i);
        }
        for(int i=n-1;i>0;i--) //然后将最大的换到后面  然后此时前n-1个又不满足大顶堆,再从开始处shiftdown
        {
            swap(arr[0],arr[i]);
            __shiftDown(arr,i,0);
        }
    
    }
    
    
    
    
    
    int  main()
    {
        MaxHeap  maxheap=MaxHeap(100);
        int arr[100];
        for(int i=0;i<100;i++)
        {
           arr[i]=100-i;
        }
         for(int i=0;i<100;i++)
        {
            cout<<arr[i]<<" ";
        }
        cout<<endl;
        cout<<"-----------"<<endl;
       /* while(!maxheap.isEmpty())
        {
            cout<<maxheap.extractMax()<<" ";
        }*/
        heapSort1(arr,100);
        for(int i=0;i<100;i++)
        {
            cout<<arr[i]<<" ";
        }
        cout<<endl;
        cout<<"-----------"<<endl;
    
        heapSort2(arr,100);//效率还是快的
        for(int i=0;i<100;i++)
        {
            cout<<arr[i]<<" ";
        }
            cout<<endl;
        cout<<"-----------"<<endl;
        heapSort(arr,100);//效率还是快的
        for(int i=0;i<100;i++)
        {
            cout<<arr[i]<<" ";
        }
        return 0;
    }
  • 相关阅读:
    公安备案接入服务商如何填写?(网站接入信息)
    VSCode 开发Vue必备插件
    阿里云ecs从零配置centos 安装宝塔bt环境 (安装失败提示setuptools installation failed)
    hover时下划线从中间向两端渐变
    phpcms v9后台增加阅读量字段,可任意修改阅读量
    织梦登录后台变空白解决方法大全
    html鼠标滚动后导航栏吸顶效果
    关于height:100%和height:100vh的区别
    mycat
    Hash碰撞
  • 原文地址:https://www.cnblogs.com/libin123/p/11448428.html
Copyright © 2011-2022 走看看