永发信息网

什么是堆排序

答案:1  悬赏:20  手机版
解决时间 2021-03-23 08:05
  • 提问者网友:锁深秋
  • 2021-03-22 15:38
什么是堆排序
最佳答案
  • 五星知识达人网友:未来江山和你
  • 2021-03-22 15:56
堆排序
1、 堆的定义
堆是一个含有n个关键字{k1,k2,…,kn}的序列,且具有如下特性:
ki<=k2i
且 ki<=k2i+1 (1<=i<=n/2) (1)

ki>=k2i
且 ki>=k2i+1 (1<=i<=n/2) (2)
ki>=k2i
满足式(1)的称为极小化堆,或极小堆,或小堆,满足式(2)的称为极大化堆,或极大堆,或大堆。本节以极小化堆为例子进行讲解。
堆与完全二叉树的关系:堆是n个元素(关键字)的序列,满足完全二叉树顺序存储中结点间的关系(双亲与子女序号间的关系)。
17,28,51,33,62,96,87,51 是小顶堆
96,51,87,33,28,62,51,17 是大顶堆

二叉堆
2、 堆排序的基本问题
既然堆顶元素(关键字)是最小元素,所以它是排序序列的最小元素,输出后,将其它元素再调整成堆,新的堆顶元素是排序序列的第二个元素。如此下去,通过堆,可将一个无序序列变为一个有序序列。因此,堆排序的基本问题是:
(1) 如何建堆
(2) 如何调堆
3、 如何调堆
将最后一个元素和堆顶元素交换(相当将堆顶元素输出)后,这时,从堆顶到倒数第二元素,除堆顶元素外,其余元素均符合堆的定义。下面采用筛选法,把包括堆顶元素在内的所有元素调成堆。大堆根
void Sift(RecType R[],int i,int m)
{ ‖假设R[i+1..m]中各元素满足堆的定义,本算法调整R[i]使序列
‖R[i..m]中各元素满足堆的性质
R[0]=R[i]; ‖暂存“根”记录R[i]
for(j=2*i; j<=m; j*=2) ‖j<=m时,R[2i]是R[i]的左孩子
{ if(j‖若R[i]的右孩子存在,且关键字大于左孩子,j指向R[i]的右孩子
if(R[0].key { R[i]=R[j]; ‖将R[j]换到双亲位置上
i=j; ‖修改当前被调整结点
}
else break; ‖调整完毕,退出循环
}‖for
R[i]=R[0]; ‖最初被调整结点放入正确位置
}‖Sift

4、 如何建堆
具有n个结点的完全二叉树,其叶子结点被认为符合堆的定义,其最后一个非终端结点的编号是n/2,若从该结点开始,直到根结点,依次调用上面的筛选法,则可完成堆的建立。具体算法放在下面堆排序算法中。
5、 堆排序算法
void HeapSort(RecType R[],int n)
{ ‖对记录序列R[1..n]进行堆排序。
for(i=n/2;i>0;i--) ‖把R[1..n]建成大顶堆
Sift(R,i,n);
for(i=n;i>1;i--)
{ ‖将堆顶记录和当前未经排序子序列R[1..i]中最后一个记录相互交换
R[1]←→R[i];
Sift(R,1,i-1); ‖将R[1..i-1]重新调整为大顶堆
}‖for
}‖HeapSort
6、 堆排序算法分析
时间复杂度为O(nlogn),只需要一个记录大小供交换用的辅助存储空间。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯