科技: 人物 企业 技术 IT业 TMT
科普: 自然 科学 科幻 宇宙 科学家
通信: 历史 技术 手机 词典 3G馆
索引: 分类 推荐 专题 热点 排行榜
互联网: 广告 营销 政务 游戏 google
新媒体: 社交 博客 学者 人物 传播学
新思想: 网站 新书 新知 新词 思想家
图书馆: 文化 商业 管理 经济 期刊
网络文化: 社会 红人 黑客 治理 亚文化
创业百科: VC 词典 指南 案例 创业史
前沿科技: 清洁 绿色 纳米 生物 环保
知识产权: 盗版 共享 学人 法规 著作
用户名: 密码: 注册 忘记密码?
    创建新词条
科技百科
  • 人气指数: 2198 次
  • 编辑次数: 1 次 历史版本
  • 更新时间: 2009-03-18
admin
admin
发短消息
相关词条
Intel Smart Connect
Intel Smart Connect
THX
THX
电容式触摸屏
电容式触摸屏
USB 3.0
USB 3.0
超速计算机芯片
超速计算机芯片
相变存储技术
相变存储技术
超级计算机模拟图
超级计算机模拟图
笔记本常见接口
笔记本常见接口
UEFI
UEFI
WebP
WebP
推荐词条
希拉里二度竞选
希拉里二度竞选
《互联网百科系列》
《互联网百科系列》
《黑客百科》
《黑客百科》
《网络舆情百科》
《网络舆情百科》
《网络治理百科》
《网络治理百科》
《硅谷百科》
《硅谷百科》
2017年特斯拉
2017年特斯拉
MIT黑客全纪录
MIT黑客全纪录
桑达尔·皮查伊
桑达尔·皮查伊
阿里双十一成交额
阿里双十一成交额
最新词条

热门标签

微博侠 数字营销2011年度总结 政务微博元年 2011微博十大事件 美国十大创业孵化器 盘点美国导师型创业孵化器 盘点导师型创业孵化器 TechStars 智能电视大战前夜 竞争型国企 公益型国企 2011央视经济年度人物 Rhianna Pratchett 莱恩娜·普莱契 Zynga与Facebook关系 Zynga盈利危机 2010年手机社交游戏行业分析报告 游戏奖励 主流手机游戏公司运营表现 主流手机游戏公司运营对比数据 创建游戏原型 正反馈现象 易用性设计增强游戏体验 易用性设计 《The Sims Social》社交亮 心理生理学与游戏 Kixeye Storm8 Storm8公司 女性玩家营销策略 休闲游戏的创新性 游戏运营的数据分析 社交游戏分析学常见术语 游戏运营数据解析 iPad风行美国校园 iPad终结传统教科书 游戏平衡性 成长类型及情感元素 鸿蒙国际 云骗钱 2011年政务微博报告 《2011年政务微博报告》 方正产业图谱 方正改制考 通信企业属公益型国企 善用玩家作弊行为 手机游戏传播 每用户平均收入 ARPU值 ARPU 游戏授权三面观 游戏设计所运用的化学原理 iOS应用人性化界面设计原则 硬核游戏 硬核社交游戏 生物测量法研究玩家 全球移动用户 用户研究三部曲 Tagged转型故事 Tagged Instagram火爆的3大原因 全球第四大社交网络Badoo Badoo 2011年最迅猛的20大创业公司 病毒式传播功能支持的游戏设计 病毒式传播功能 美国社交游戏虚拟商品收益 Flipboard改变阅读 盘点10大最难iPhone游戏 移动应用设计7大主流趋势 成功的设计文件十个要点 游戏设计文件 应用内置付费功能 内置付费功能 IAP功能 IAP IAP模式 游戏易用性测试 生理心理游戏评估 游戏化游戏 全美社交游戏规模 美国社交游戏市场 全球平板电脑出货量 Facebook虚拟商品收益 Facebook全球广告营收 Facebook广告营收 失败游戏设计的数宗罪名 休闲游戏设计要点 玩游戏可提高认知能力 玩游戏与认知能力 全球游戏广告 独立开发者提高工作效率的100个要点 Facebook亚洲用户 免费游戏的10种创收模式 人类大脑可下载 2012年最值得期待的20位硅谷企业家 做空中概股的幕后黑手 做空中概股幕后黑手 苹果2013营收 Playfish社交游戏架构

 

目录

[显示全部]

发明者编辑本段回目录

1991年计算机先驱奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德(Robert W.Floyd)和威廉姆斯(J.Williams)在1964年共同发明了著名的堆排序算法HEAPSORT

http://202.207.12.200/whjc/jisuanjifazhanshi/xianqu/65.htm

1、 堆排序定义编辑本段回目录



n个关键字序列Kl,K2,…,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质):

(1) ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤ )

若将此序列所存储的向量R【1..n】看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。

【例】关键字序列(10,15,56,25,30,70)和(70,56,30,25,15,10)分别满足堆性质(1)和(2),故它们均是堆,其对应的完全二叉树分别如小根堆示例和大根堆示例所示。

2、大根堆和小根堆编辑本段回目录



根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆。

根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆。

注意:

①堆中任一子树亦是堆。

②以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义k叉堆。

3、堆排序特点编辑本段回目录



堆排序(HeapSort)是一树形选择排序。

堆排序的特点是:在排序过程中,将R【l..n】看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系【参见二叉树的顺序存储结构】,在当前无序区中选择关键字最大(或最小)的记录。

4、堆排序与直接插入排序的区别编辑本段回目录



直接选择排序中,为了从R【1..n】中选出关键字最小的记录,必须进行n-1次比较,然后在R【2..n】中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作。

堆排序可通过树形结构保存部分比较结果,可减少比较次数。

5、堆排序编辑本段回目录



堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。

(1)用大根堆排序的基本思想

① 先将初始文件R【1..n】建成一个大根堆,此堆为初始的无序区

② 再将关键字最大的记录R【1】(即堆顶)和无序区的最后一个记录R【n】交换,由此得到新的无序区R【1..n-1】和有序区R【n】,且满足R【1..n-1】.keys≤R【n】.key

③ 由于交换后新的根R【1】可能违反堆性质,故应将当前无序区R【1..n-1】调整为堆。然后再次将R【1..n-1】中关键字最大的记录R【1】和该区间的最后一个记录R【n-1】交换,由此得到新的无序区R【1..n-2】和有序区R【n-1..n】,且仍满足关系R【1..n-2】.keys≤R【n-1..n】.keys,同样要将R【1..n-2】调整为堆。

……

直到无序区只有一个元素为止。

(2)大根堆排序算法的基本操作:

① 初始化操作:将R【1..n】构造为初始堆

② 每一趟排序的基本操作:将当前无序区的堆顶记录R【1】和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。

注意:

①只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。

②用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反:在任何时刻,堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。

(3)堆排序的算法:

void HeapSort(SeqIAst R)

{ //对R【1..n】进行堆排序,不妨用R【0】做暂存单元

int i;

BuildHeap(R); //将R【1-n】建成初始堆

for(i=n;i>1;i--){ //对当前无序区R【1..i】进行堆排序,共做n-1趟。

R【0】=R【1】;R【1】=R;R=R【0】; //将堆顶和堆中最后一个记录交换

Heapify(R,1,i-1); //将R【1..i-1】重新调整为堆,仅有R【1】可能违反堆性质

} //endfor

} //HeapSort

(4) BuildHeap和Heapify函数的实现

因为构造初始堆必须使用到调整堆的操作,先讨论Heapify的实现。

① Heapify函数思想方法

每趟排序开始前R【l..i】是以R【1】为根的堆,在R【1】与R交换后,新的无序区R【1..i-1】中只有R【1】的值发生了变化,故除R【1】可能违反堆性质外,其余任何结点为根的子树均是堆。因此,当被调整区间是R【low..high】时,只须调整以R【low】为根的树即可。

"筛选法"调整堆

R【low】的左、右子树(若存在)均已是堆,这两棵子树的根R【2low】和R【2low+1】分别是各自子树中关键字最大的结点。若R【low】.key不小于这两个孩子结点的关键字,则R【low】未违反堆性质,以R【low】为根的树已是堆,无须调整;否则必须将R【low】和它的两个孩子结点中关键字较大者进行交换,即R【low】与R【large】(R【large】.key=max(R【2low】.key,R【2low+1】.key))交换。交换后又可能使结点R【large】违反堆性质,同样由于该结点的两棵子树(若存在)仍然是堆,故可重复上述的调整过程,对以R【large】为根的树进行调整。此过程直至当前被调整的结点已满足堆性质,或者该结点已是叶子为止。上述过程就象过筛子一样,把较小的关键字逐层筛下去,而将较大的关键字逐层选上来。因此,有人将此方法称为"筛选法"。

算法实例:

#include<stdio.h>

#include<stdlib.h>

inline int LEFT(int i);

inline int RIGHT(int i);

inline int PATENT(int i);

void MAX_HEAPIFY(int A【】,int heap_size,int i);

void BUILD_MAX_HEAP(int A【】,int heap_size);

void HEAPSORT(int A【】,int heap_size);

void output(int A【】,int size);

int main()

{

FILE *fin;

int m,size,i;

fin = fopen("array.in","r");

int* a;

fscanf(fin," %d",&size);

a = (int *)malloc(size + 1);

a【0】=size;

for(i = 1;i <= size; i++ )

{

fscanf(fin," %d",&m);

a = m;

}

HEAPSORT(a,a【0】);

printf("$$$$$$$$$$The Result$$$$$$$$n");

output(a,a【0】);

free(a);

return 0;

}

inline int LEFT(int i)

{

return 2 * i;

}

inline int RIGHT(int i)

{

return 2 * i + 1;

}

inline int PARENT(int i)

{

return i / 2;

}

void MAX_HEAPIFY(int A【】,int heap_size,int i)

{

int temp,largest,l,r;

largest = i;

l = LEFT(i);

r = RIGHT(i);

if ((l <= heap_size) && (A【l】 > A)) largest = l;

if ((r <= heap_size) && (A【r】 > A【largest】)) largest = r;

if (largest != i)

{

temp = A【largest】;

A【largest】 = A;

A = temp;

MAX_HEAPIFY(A,heap_size,largest);

}

}

void BUILD_MAX_HEAP(int A【】,int heap_size)

{

int i;

for (i = heap_size / 2;i >= 1;i--) MAX_HEAPIFY(A,heap_size,i);

}

void HEAPSORT(int A【】,int heap_size)

{

int i;

BUILD_MAX_HEAP(A,heap_size);

for (i = heap_size;i >= 2; i--)

{

int temp;

temp = A【1】;

A【1】 = A;

A = temp;

MAX_HEAPIFY(A,i-1,1);

}

}

void output(int A【】,int size)

{

int i = 1;

FILE *out = fopen("result.in","w+");

for (; i <= size; i++){

printf("%d ",A);

fprintf(out,"%d ",A);

}

printf("n");

}

②BuildHeap的实现

要将初始文件R【l..n】调整为一个大根堆,就必须将它所对应的完全二叉树中以每一结点为根的子树都调整为堆。

显然只有一个结点的树是堆,而在完全二叉树中,所有序号 的结点都是叶子,因此以这些结点为根的子树均已是堆。这样,我们只需依次将以序号为 , -1,…,1的结点作为根的子树都调整为堆即可。

具体算法【参见教材】。

5、大根堆排序实例

对于关键字序列(42,13,24,91,23,16,05,88),在建堆过程中完全二叉树及其存储结构的变化情况参见【动画演示】。

6、 算法分析

堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。

堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均性能较接近于最坏性能。

由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。

堆排序是就地排序,辅助空间为O(1),

它是不稳定的排序方法。

参考资料:http://www.wikilib.com/wiki?title=%E5%A0%86%E6%8E%92%E5%BA%8F&;diff=prev&oldid=374531

→如果您认为本词条还有待完善,请 编辑词条

词条内容仅供参考,如果您需要解决具体问题
(尤其在法律、医学等领域),建议您咨询相关领域专业人士。
0

标签: 堆排序

收藏到: Favorites  

同义词: 暂无同义词

关于本词条的评论 (共0条)发表评论>>

对词条发表评论

评论长度最大为200个字符。