热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

归并,快速,堆排序~

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

堆排序

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

  (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个关键字即可以使得文件递增有序。

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

特点

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

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

不稳定的排序算法

代码

View Code

1 void adjust(int i,int n)//调整为小顶堆
2 {
3 int j = i,k;
4 a[0] = a[i];
5 j = 2*i;
6 while(j<&#61;n)
7 {
8 if(j a[j&#43;1])//左右孩子结点的最小值
9 j&#43;&#43;;
10 if(a[0]>a[j])//如果比最小值大
11 {
12 a[i] &#61; a[j];//当前最小值孩子结点上移 i变为当前j值 继续与下面比较
13 i &#61; j;
14 j &#61; 2*j;
15 }
16 else
17 break;
18 }
19 a[i] &#61; a[0];//放在合适位置
20 }
21 void heapsort(int n)
22 {
23 int i,t;
24 for(i &#61; n/2 ; i>0 ; i--)//最初调整为堆
25 adjust(i,n);
26 for(i &#61; n ; i>1 ; i--)//依次交换根节点和尾结点
27 {
28 t &#61; a[1];
29 a[1] &#61; a[i];
30 a[i] &#61; t;
31 adjust(1,i-1);
32 }
33 }

 快速排序

设要排序的数组是A[0]……A[N-1]&#xff0c;首先任意选取一个数据&#xff08;通常选用第一个数据&#xff09;作为关键数据&#xff0c;然后将所有比它小的数都放到它前面&#xff0c;所有比它大的数都放到它后面&#xff0c;这个过程称为一趟快速排序。值得注意的是&#xff0c;快速排序不是一种稳定的排序算法&#xff0c;也就是说&#xff0c;多个相同的值的相对位置也许会在算法结束时产生变动。

最坏 时间复杂度为o&#xff08;n2&#xff09;。

最佳 T(n)&#61;θ&#xff08;nlogn)

代码

View Code

1 /*
2 一趟快速排序的算法是&#xff1a;   
3 找一个记录&#xff0c;以它的关键字作为“枢轴”&#xff0c;
4 凡其关键字小于枢轴的记录均移动至该记录之前&#xff0c;
5 反之&#xff0c;凡关键字大于枢轴的记录均移动至该记录之后。
6 A[0] A[1] A[2] A[3] A[4] A[5] A[6]&#xff1a;   
7 49 38 65 97 76 13 27    8 进行第一次交换后&#xff1a;
9 27 38 65 97 76 13 49   
10 进行第二次交换后&#xff1a;
11 27 38 49 97 76 13 65   
12 进行第三次交换后&#xff1a;27 38 13 97 76 49 65    
13 进行第四次交换后&#xff1a;27 38 13 49 76 97 65
14 */
15 int fqsort(int low,int high,int a[])
16 {
17 int i &#61; low,j &#61; high,k &#61; a[low];//找一个比较的点
18 while(i<j)
19 {
20 while(i//从右向左移直至找到比k大的数
21 j--;
22 a[i] &#61; a[j];//比这个数大的放左边
23 while(i&#61;k)//从左向右移直至找到比k小的数
24 i&#43;&#43;;
25 a[j] &#61; a[i];//比这个数大的放右边
26 }
27 a[i] &#61; k;
28 return j;//j左右两边已经被k分割开 再把j&#43;1当作右边一组的low j-1当作左边一组的high进行下一次的快排
29 }
30 void qsort(int low,int high,int a[])
31 {
32 int q;
33 if(low<high)
34 {
35 q &#61; fqsort(low,high,a);//找到分割点
36 qsort(low,q-1,a);//左右两边进行快排
37 qsort(q&#43;1,high,a);
38 }
39 }

 归并排序

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。

将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有序&#xff0c;再使子序列段间有序。若将两个有序表合并成一个有序表&#xff0c;称为2-路归并。

归并排序是稳定的排序.即相等的元素的顺序不会改变.如输入记录 1(1) 3(2) 2(3) 2(4) 5(5) (括号中是记录的关键字)时输出的 1(1)
2(3) 2(4) 3(2) 5(5) 中的2 和 2
是按输入的顺序.这对要排序数据包含多个信息而要按其中的某一个信息排序,要求其它信息尽量按输入的顺序排列时很重要.这也是它比快速排序优势的地方.

 代码

View Code

1 void msort(int low,int mid,int high)//将两部分归并
2 {
3 int i,j,n1 &#61; mid-low&#43;1,n2 &#61; high-mid,x[10001],y[10001];
4 for(i &#61; 1 ; i <&#61; n1 ; i&#43;&#43;)//存于两个数组中
5 x[i] &#61; a[low&#43;i-1];
6 for(i &#61; 1 ; i <&#61; n2 ; i&#43;&#43;)
7 y[i] &#61; a[mid&#43;i];
8 int k &#61; low;
9 i &#61; 1;
10 j &#61; 1;
11 while(i<&#61;n1&&j<&#61;n2)//排序
12 {
13 if(x[i]<y[j])
14 a[k] &#61; x[i&#43;&#43;];
15 else
16 a[k] &#61; y[j&#43;&#43;];
17 k&#43;&#43;;
18 }
19 while(i<&#61;n1)
20 a[k&#43;&#43;] &#61; x[i&#43;&#43;];
21 while(j<&#61;n2)
22 a[k&#43;&#43;] &#61; y[j&#43;&#43;];
23 }
24 void merge(int low,int high)//二分递归合并
25 {
26 int mid;
27 if(low<high)
28 {
29 mid &#61; (low&#43;high)/2;
30 merge(low,mid);
31 merge(mid&#43;1,high);
32 msort(low,mid ,high);
33 }
34 }


转:https://www.cnblogs.com/0803yijia/archive/2012/07/21/2602307.html



推荐阅读
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 热血合击脚本辅助工具及随机数生成器源码分享
    本文分享了一个热血合击脚本辅助工具及随机数生成器源码。游戏脚本能够实现类似真实玩家的操作,但信息量有限且操作不可控。热血合击脚本辅助工具可以帮助玩家自动刷图、换图拉怪等操作,并提供了雷电云手机的扩展服务。此外,还介绍了使用mt_rand函数作为随机数生成器的代码示例。 ... [详细]
  • SAP羞辱国产软件商:技术停在10年前
    SAP中国研究院总裁芮祥麟表示,国产软件厂商过于热衷概念炒作,技术水平停留在10年前的客户端架构水平。他认为,国内厂商推出基于SOA的产品或转型SAAS模式是不可能的,研发新架构需要时间。当前最热门的概念是云计算,芮祥麟呼吁国产厂商应该潜心研发底层架构。 ... [详细]
  • REVERT权限切换的操作步骤和注意事项
    本文介绍了在SQL Server中进行REVERT权限切换的操作步骤和注意事项。首先登录到SQL Server,其中包括一个具有很小权限的普通用户和一个系统管理员角色中的成员。然后通过添加Windows登录到SQL Server,并将其添加到AdventureWorks数据库中的用户列表中。最后通过REVERT命令切换权限。在操作过程中需要注意的是,确保登录名和数据库名的正确性,并遵循安全措施,以防止权限泄露和数据损坏。 ... [详细]
  • 本文详细介绍了使用 SQL Load 和 Excel 的 Concatenate 功能将数据导入 ORACLE 数据库的方法和步骤,同时介绍了使用 PL/SQL tools 将数据导入临时表的方法。此外,还提供了一个转链接,可参考更多相关内容。摘要共计XXX字。 ... [详细]
author-avatar
文文的爱天使_152
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有