排序算法-堆排序
Posted 梦想田园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法-堆排序相关的知识,希望对你有一定的参考价值。
/*堆排序的基本思想:将所有元素初始化一个最大堆,然后将第一个元素即最大元素与最后一个元素交换;
再对前n-1个元素调整为一个最大堆,就这样依次进行,每次都是把最大元素放到最后边。
*/
void MaxHeapify(int*list,int size,int root)
int lChild=2*(root+1)-1,rChild=lChild+1;//根节点的左右孩子节点
while(rChild<size)//如果右孩子节点存在
if(list[root]>=list[lChild]&&list[root]>=list[rChild])//如果根节点大于左右孩子节点表明以root为根节点的树已经为最大堆
return;
if(list[lChild]>list[rChild])//如果左孩子大,则选左孩子作为根节点
int temp=list[lChild];
list[lChild]=list[root];
list[root]=temp;
root=lChild;
else//右孩子大
int temp=list[rChild];
list[rChild]=list[root];
list[root]=temp;
root=rChild;
lChild=2*(root+1)-1;
rChild=lChild+1;
if(lChild<size)//如果只有左孩子存在,说明已到最后
if(list[lChild]>list[root])
int temp=list[lChild];
list[lChild]=list[root];
list[root]=temp;
//采用迭代实现的堆排序
void HeapSortByIteration(int*list,int size)
int last;//最后一个有孩子的节点
if((size-1)%2==0)//该节点既有左孩子,又有右孩子
last=(size-1-2)/2;
else
last=(size-1-1)/2;
for(int i=last;i>=0;i--)//初始化最大堆
MaxHeapify(list,size,i);
while(size>1)
//交换根元素和最后一个元素的位置
int temp=list[0];
list[0]=list[size-1];
list[size-1]=temp;
MaxHeapify(list,--size,0);
//采用递归实现的堆排序存在有失效率的问题,看如下代码
//相当于是每次都要对堆进行一次初始化
void HeapSortByRecursion(int*list,int size)
if(size==1)
return;
int last;//最后一个有孩子的节点
if((size-1)%2==0)//该节点既有左孩子,又有右孩子
last=(size-1-2)/2;
else
last=(size-1-1)/2;
for(int i=last;i>=0;i--)//初始化最大堆
MaxHeapify(list,size,i);
//交换根元素和最后一个元素的位置
int temp=list[0];
list[0]=list[size-1];
list[size-1]=temp;
HeapSortByRecursion(list,--size);
//堆排序的时间复杂度分析
/*
1.堆排序的时间主要由两部分组成,一部分是建堆时间,另一部分是调整堆的时间。
建堆的时间是O(n),调整堆的时间为O(nlogn)。至于建堆时间可用数学公式进行推导,例如有(1/2)n的元素进行了一次比较,
(1/4)n的元素进行了进行了2次比较,(1/8)n的元素进行了3次比较,....,于是可推出最终的总比较次数O(n);至于调整堆的时间
由于树的高度为log(n),大部分节点都进行了log(n)次的比较,因此时间为O(nlogn)。
2.仔细分析会发现堆排序对于数据的初始顺序状态并不太敏感,即无论初始状态怎么样都要首先建立一个最大堆,所以堆排序的最好最坏的时间
复杂度均为nlog(n)。
3.由于建堆的时间比较多,因此堆排序并不太适合排序元素量比较少的情况
*/
以上是关于排序算法-堆排序的主要内容,如果未能解决你的问题,请参考以下文章
插入排序(直接插入排序希尔排序);交换排序(冒泡排序快速排序);选择排序(简单选择排序堆排序);归并排序和基数排序;基于关键词比较的排序算法下界分析