算法导论笔记(3)
堆排序
思想
二叉堆被看成一个近似的完全二叉树,树上每一个结点对应数组中的一个元素。除了最底层以外,该树是完全充满的。
PARENT(i) return i/2
父节点
LEFT(i) return 2*i;
左节点
RIGHT(i) return 2*i+1
右节点
分为最大堆和最小堆
最大堆满足A[PARENT(I)]>A[I]
最小堆满足A[I]<A[PARENT(I)]
堆的高度lg(n)
共四种操作
- MaxHeapify 复杂度lg(n),维护最大堆
- BuildMaxHeap 线性复杂度,构造最大堆
- HeapSort 堆排
- MaxInsert,HeapExtractMax,HeapIncreaseKey,HeapMaximun 利用堆实现优先队列
`
void MaxHeapify(int *A,int i,int size){
int left=i*2,
right=i*2+1,
large=i;
if(i>size/2){
return;
}
if(A[left]>A[large]&&left<=size){
large=left;
}
if(A[right]>A[large]&&right<=size){
large=right;
}
if(large!=i){
swap(A[i],A[large]);
MaxHeapify(A,large,size);
}
}
void BuildMaxHeap(int *A,int size){
int i=size/2;
for(int j=i;j>=1;j--){
MaxHeapify(A,j,size);
}
}
void HeapSort(int *A,int size){
BuildMaxHeap(A,size);
swap(A[1],A[size]);
for(int i=size-1;i>=2;i--)
{
MaxHeapify(A,1,i); //重新调整堆顶节点成为大顶堆
swap(A[1],A[i]); //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
}
}
int main(int argc, char *argv[])
{
int a[100];
int size,i=1;
scanf("%d",&size);
for(i=1;i<=size;i++)
cin>>a[i];
HeapSort(a,size);
for(i=1;i<=size;i++)
cout<<a[i]<<"";
cout<<endl;
return 0;
}
`
可以通过堆构造优先队列。