堆排序:时间复杂度nlgn
ITA定义堆的数组表示法为1-10,所以a[0]暂用无处,比如,长度为10的堆,则用a[1]-a[10]表示,建立时的长度要比实际长度多1
几个常见操作
HEAPIFY:函数原型maxheapify(int *a,int i):表示将数组a从当前位置i开始建立最大堆(或最小堆),取左右孩子中最大值与根节点交换,并以交换后的孩子结点为i进行递归调用
BUILD-MAX-HEAP:函数原型buildMaxHeap(int *a,int length):从length/2位到第1位循环调用maxheapify函数即可,即保证最后建成的是一个最大堆
优先级队列:(用堆实现)
常用的几个操作:
HEAP-MAX:直接return a[1]即可
EXACT-MAX:返回最大值,并取出最大值:返回a[1]后,将a[length]与a[1]交换,并将长度减1,最后执行maxheapify(a,1)即可,即再次建堆
HEAP-INCREASE-KEY:函数原型heapIncreaseKey(int *a,int i,int key),将a[i]的值变为key(key应比a[i]大,否则无意义):问题的关键在于a[i]的值变为key后会不会超过原来a[i]的父亲节点,因此多加一个判断和交换即可
HEAP-INSERT:函数原型:heapInsert(int *a,int key):在堆a中插入新元素key
原理:因为a[length]手动置为负无穷,所以heapIncreaseKey(a,length,key)调用后key一定比a[length]要大,因此会执行相应操作
将一个数组建最大堆并进行堆排序的实现(C++)
void exchange(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void maxHeapify(int *a,int i,int length)
{
int l=2*i;
int r=2*i+1;
int largest;
if(l<=length && a[l]>a[i] )
largest=l;
else
largest=i;
if(r<=length && a[r]>a[largest])
largest=r;
if(largest!=i)
{
exchange(a[i],a[largest]);
maxHeapify(a,largest,length);
}
}
void printArray(int *a,int arraylength)
{
for(int i=0;i!=arraylength;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
void buildMaxHeap(int *a,int arraylength)
{
int length=arraylength-1;
for(int i=length/2;i!=0;i--)
{
maxHeapify(a,i,length);
}
}
void heapSort(int *a,int arraylength)
{
int length=arraylength-1;
for(int i=length;i!=1;i--)
{
exchange(a[i],a[1]);
length--;
maxHeapify(a,1,length);
}
}