------------恢复内容开始------------
一、为什么要引入堆排序
- 在日常生活中,很多场景需要优先队列。
应用场景一:动态请求。比如队伍中不断的入队和出队,并且优先级是动态调整,此时用堆比较合适。
应用场景二: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),从 第一个非叶子节点开始
------------恢复内容结束------------