堆排序

------------恢复内容开始------------

一、为什么要引入堆排序

  •  在日常生活中,很多场景需要优先队列。

          应用场景一:动态请求。比如队伍中不断的入队和出队,并且优先级是动态调整,此时用堆比较合适。

          应用场景二:M个数字中求前N个大的数。

  •  什么是优先队列?

         普通队列是先进先出,后进后出;优先队列是出队顺序和入队顺序无关,与优先级有关,并且优先级是动态调整的。

  •  优先队列的主要操作

         入队,出队(取出优先级最高的元素)

  •   优先队列的实现

     

     显然堆去实现优先队列更合适。

二、堆的基本存储

  1.百度百科的定义

      堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:
  • 堆中某个节点的值总是不大于或不小于其父节点的值;(最大堆或最小堆)
  • 堆总是一棵完全二叉树。

  2.堆的实现:数组

/**
*** 最大堆类 
**/
template<typename Item>
class MaxHeap{
    private:
        Item* data;
        count;
    
    public:
        //构造函数,由用户传入堆的容量 
        MaxHeap(int capacity){
            data = new Item[capacity+1];
        }
        
        ~MaxHeap(){
            delete [] data;
        } 
        
        int size(){
            return count;
        } 
        
        bool isEmpty(){
            return count == 0;
        }
}; 

   

三、堆的操作

1.向堆里添加一个元素--shiftUp

    //向堆中插入一个新元素 
        void insert(Item item){
            //注意:可能数组越界;或者容量不够申请 
             assert(count + 1 <= capacity);
            data[count+1] = item;
            count++;
            ShiftUp(count);
        }


    void ShiftUp(int k){
            
            while(k> 1 && data[k/2] < data[k]){
                swap(data[k/2],data[k]);
                k /= 2; 
            }
        } 

2.从堆中取出一个元素--Shift  Down

类似于出队,取出最大的数。

3.堆排序

法一:将n个元素逐个插入到一个空堆中,时间复杂度是 o(nlogn),

法二:heapify的过程,时间复杂度是 o(n),从 第一个非叶子节点开始

------------恢复内容结束------------

原文地址:https://www.cnblogs.com/juanzhi/p/12322426.html