关于堆排序的学习总结
堆的定义
? n个元素的序列{k1,k2,···,kn},当满足(k1 <= k2, ki <= k2i+1)或(k1 >= k2, ki >= k2i+1)时,可称之为堆。
? 若将堆看作二叉树,则有两种形式(大根堆,小根堆),即层序遍历每一层都比上一层小(大);而堆顶元素(完全二叉树的根)必为其序列的最大(小)值;
? 1-1大根堆与小根堆
堆的排序
? 其实堆排序可以用一句话来概括:“创建堆,用***最末值***替出***堆顶***,再重新***创建堆***。如此往复。”
? 但要注意一点,两次的***创建堆***相似但不完全一样。
? 第一次的创建堆是自下而上的,调用n/2次创建函数。
? 第二次的创建堆只需调用一次函数。
void create_heap(int* arr,size_t len,int root)
{
while(root*2 <= len)
{
int max = root*2;
if(max+1<len && arr[max-1] < arr[max])
max++;
if(arr[root-1] > arr[max-1])
return;
swap(arr[root-1],arr[max-1]);
root = max;
}
}
void heap_sort(int* arr,size_t len)
{
for(int i=len/2; i>0; i--)
create_heap(arr,len,i);
for(int i=len-1; i>0; i--)
{
swap(arr[0],arr[i]);
create_heap(arr,i,1);
}
show_sort_result(__func__,arr,len);
}
堆排序的性能
? 其时间复杂度为O(nlogn),其运行时间主要耗费在***建初始堆***和调整建新堆时进行的反复***筛选***上。
|