Heapsort
Heaps
- Data structure indexed by integers 1, 2, …, n.
- Each element supports the operation PARENT, LEFT, RIGHT.
- Easily implemented using an array with
PARENT(i) = i/2向下取整, LEFT(i) = 2i, and RIGHT(i) = 2i + 1.
-
max heap
A[PARENT(i)] ≥ A[i]
-
min heap
A[PARENT(i)] ≤ A[i]
-
The root of the heap is A[1]. The height of a node is the longest downward path from the node to a leaf. The height of the heap is the height of the root.
如图为一大顶堆。(以二叉树形式表示) -
The height of heap with n elements is
-
Operations supported by a heap:
MAX-HEAPIFY
ensures that a heap is max heap. O(lg n)
BUILD-MAX-HEAP
produces a max heap from an unordered array. Θ(n) -
To sort an array, we can first convert it into a max heap, repeatedly extract the root (the largest element by definition) and MAX-HEAPIFY the
rest. Θ(n lg n)
MAX-HEAPIFY:
其中h=lgn向下取整。
void MAX_HEAPIFY(int A[],int i)
{
int l=2*i+1;
int r=2*i+2;
int largest;
if(l<heapsize&&A[l]>A[i])//左节点大于父节点
largest=l;
else
largest=i;
if(r<heapsize&&A[r]>A[largest])//左节点小于右节点
largest=r;
if(largest!=i)//若左右孩子有一个比该节点大的交换更大的值
{
int x=A[i];
A[i]=A[largest];
A[largest]=x;
MAX_HEAPIFY(A,largest);
}
}
BUILD-MAX-HEAP:
void BUILD_MAX_HEAP(int A[])
{
for(int i=heapsize/2-1;i>=0;i--)//从中间位置调用从而降低时间复杂度
{
MAX_HEAPIFY(A,i);
}
}
因此中点之后的节点均为叶子节点。
例子如下:
nlgn不够准确。
HEAPSORT:
void HEAPSORT(int A[])
{
BUILD_MAX_HEAP(A);
for(int i=9;i>=0;i--)//不断把堆的最后一个元素换到堆顶,从而找出每次的最大值
{
int x=A[0];
A[0]=A[i];
A[i]=x;
heapsize--;
MAX_HEAPIFY(A,0);
}
}
使用主函数进行验证:
int main()
{
int A[]={4,1,3,2,16,9,10,14,8,7};
HEAPSORT(A);
for(int i=0;i<10;i++)
{
cout<<A[i]<<" ";
}
}
结果:
1 2 3 4 7 8 9 10 14 16
Priority Queue(优先队列)
- 优先队列是一种用来维护由一组元素构成的集合S的数据结构,其中每一个元素都有一个相关的值,称为
关键字(key)
。 - There are two kinds of priority queues:
max-priority queues
andmin-priority queues
.
最大优先队列支持一下几种操作: - INSERT(S, x):inserts the element x into S
- MAXIMUM(S):returns the element of S with the largest key
- EXTRACT-MAX(S):removes and returns the element of S with the largest key
- INCREASE-KEY(S, x, k):Increase the value of key of element x to the new value k.
int MAXIMUM(int A[])
{
return A[0];
}
int HEAP_EXTRACT_MAX(int A[])
{
if(heapsize<1)
{
cout<<"heap underflow";
return;
}
int max=A[0];
A[0]=A[heapsize];
heapsize--;
MAX_HEAPIFY(A,0);
return max;
}
int parent(int i)
{
return (i-1)/2;
}
void HEAP_INCREASE_KEY(int A[],int i,int key)//O(lg n)
{
if(key<A[i])
{
cout<<"new key is small than current key";
return;
}
A[i]=key;
while(i>0&&A[parent(i)]<A[i])
{
int x=A[i];
A[i]=A[parent(i)];
A[parent(i)]=x;
i=parent(i);
}
}
键值增长过程:
void MAX_HEAP_INSERT(int A[],int key)
{
heapsize++;
A[heapsize-1]=key-1;//表示无穷大
HEAP_INCREASE_KEY(A,heapsize,key);
}