排序算法-堆排序
2016-06-28 13:50
316 查看
/*
堆排序的基本思想:将所有元素初始化一个最大堆,然后将第一个元素即最大元素与最后一个元素交换;
再对前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.由于建堆的时间比较多,因此堆排序并不太适合排序元素量比较少的情况
*/
堆排序的基本思想:将所有元素初始化一个最大堆,然后将第一个元素即最大元素与最后一个元素交换;
再对前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.由于建堆的时间比较多,因此堆排序并不太适合排序元素量比较少的情况
*/
相关文章推荐
- ios webview 加载含有中文的URL网页显示白屏
- EDdb 是ED数据
- java安全框架-Shiro学习笔记(七)-自定义realm
- MVC 设计模式
- (转)理解ASP.NET MVC执行过程
- 高德地图关于云检索
- cucumber java从入门到精通(2)用代码定义步骤
- java生成验证码的逻辑
- 初学CentOS——'服务'的启动管理与chkconfig用法
- javaweb学习总结(四十一)——Apache的DBUtils框架学习
- Android inputType ,软键盘输入类型
- JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
- google.maps.Map 的事件
- cscf
- 第二讲 html5 框架+Crosswalk 打包 app 以及 Angularjs 基础
- javaweb学习总结(四十)——编写自己的JDBC框架
- 提高app响应速度
- java数据转换
- DatePicker遇到的一些问题
- vmware里centos不能上网 的问题