第八章排序技术.ppt_第1页
第八章排序技术.ppt_第2页
第八章排序技术.ppt_第3页
第八章排序技术.ppt_第4页
第八章排序技术.ppt_第5页
已阅读5页,还剩77页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

内容提要 本章重点讨论四类内排序方法 即插入排序 交换排序 选择排序和归并排序 每一类排序方法都基于同一种思想 在前三类排序方法中 首先介绍一种简单的排序方法 再讨论一种改进的排序方法 学习重点 1 各种排序方法的基本思想 2 各种排序算法的执行过程 3 各种排序算法的时间复杂度及比较 学习重点 1 快速排序 堆排序 归并排序等算法的设计 2 改进算法的时间复杂度的分析 排序技术 概述 排序 给定一组数据元素 或记录 的集合 r1 r2 rn 其相应的关键码分别为 k1 k2 kn 排序是将这些元素排列成顺序为 rs1 rs2 rsn 的一个序列 使得相应的关键码满足ks1 ks2 ksn 升序 或ks1 ks2 ksn 降序 趟 在排序的过程中 基本动作执行一轮 即对待排序集合中的元素遍扫描一遍 排序技术 8 1 1排序的基本概念 排序算法的稳定性 假定在待排序的记录集中 存在多个具有相同键值的记录 若经过排序 这些记录的相对次序仍然保持不变 即在原序列中 ki kj i j 而在排序后的序列中 ri仍在rj之前 则称这种排序算法是稳定的 否则称为不稳定的 概述 排序技术 排序方法分为内排序和外排序两大类 内排序是指在排序的整个过程中 待排序的所有记录全部被放置在内存中 外排序是指由于待排序的记录个数太多 不能同时放置在内存 而需要将一部分记录放置在内存 另一部分记录放置在外存上 整个排序过程需要在内外存之间多次交换数据才能得到排序的结果 概述 排序技术 将排序方法分为基于比较的排序和不基于比较的排序 其中 基于比较的排序方法的实现主要是通过关键码的比较和记录的移动这两种操作 并且其最差时间下限已经被证明为 nlog2n 内排序大致可分为插入排序 交换排序 选择排序 归并排序等四类 内排序还可分为两类 简单的排序方法 其时间复杂度为O n2 先进的排序方法 其时间复杂度为O nlog2n 概述 排序技术 概述 排序技术 对于内排序 在排序过程中通常需进行下列两种基本操作 比较 关键码之间的比较 移动 记录从一个位置移动到另一个位置 评价排序方法的另一个主要标准是执行算法所需要的辅助存储空间 辅助存储空间是指在数据规模一定的条件下 除了存放待排序记录占用的存储空间之外 执行算法所需要的其他存储空间 8 1 2排序算法的性能 插入排序 插入排序是一类藉助 插入 进行排序的方法 其主要思想是 每次将一个待排序的记录按其关键码的大小插入到一个已经排好序的有序序列中 直到全部记录排好序为止 排序技术 无序序列 i 1 n 有序序列 1 i 直接插入排序的基本思想是 依次将待排序序列中的每一个记录插入到一个已排好序的序列中 直到全部记录都排好序 需解决的关键问题 1 如何构造初始的有序序列 2 如何查找待插入记录的插入位置 8 2 1直接插入排序 直接插入排序过程示例 25 49 25 思考r 0 的作用 16 08 r0123456 直接插入排序过程示例 思考r 0 的作用 将整个待排序的记录序列划分成有序区和无序区 初始时有序区为待排序记录序列中的第一个记录 无序区包括所有剩余待排序的记录 将无序区的第一个记录插入到有序区的合适位置中 从而使无序区减少一个记录 有序区增加一个记录 重复执行 直到无序区中没有记录为止 关键问题 1 的解决方法 将第一个记录看成是初始有序表 然后从第二个记录起依次插入到这个有序表中 直到将第n个记录插入完毕 算法描述为 for i 2 i n i 插入第i个记录 即第i趟直接插入排序 关键问题 2 的解决方法 一般情况下 在i 1个记录的有序区r 1 r i 1 中插入一个记录r i 时 首先要查找r i 的正确插入位置 然后将r i 插入到相应位置 算法描述为 r 0 r i for j i 1 r 0 r j j r j 1 r j r 0 有两个作用 一是进入查找插入位置的循环之前 它暂存了r i 的值 使得不致于因记录的后移而丢失r i 的内容 二是在查找插入位置的循环中充当 哨兵 voidinsertSort intr intn for i 2 i n i r 0 r i j i 1 for j i 1 r 0 r j j r j 1 r j j j 1 r j 1 r 0 直接插入排序算法 ifr i r i 1 直接插入排序算法性能分析 最好情况下 正序 时间复杂度为O n 最坏情况下 逆序或反序 时间复杂度为O n2 平均情况下 随机排列 时间复杂度为O n2 需要一个记录的辅助空间 直接插入排序算法是一种稳定的排序算法 算法简单 容易实现 适用于待排序记录基本有序或待排序记录较小时 8 2 2希尔排序 基本思想 先将整个待排序记录分割成若干个子序列 在子序列内分别进行直接插入排序 待整个序列中的记录基本有序时 再对全体记录进行一次直接插入排序 改进的着眼点是 1 若待排序记录按关键码基本有序时 直接插入排序的效率可以大大提高 2 由于直接插入排序算法简单 则在待排序记录数量n较小时效率也很高 需解决的关键问题 1 应如何分割待排序记录 才能保证整个序列逐步向基本有序发展 2 子序列内如何进行直接插入排序 希尔插入排序过程示例 子序列的构成不能是简单地 逐段分割 而是将相隔某个 增量 的记录组成一个子序列 接下来的问题是增量应如何取 希尔最早提出的方法是d1 n 2 di 1 di 2 算法描述为 for d n 2 d 1 d d 2 以d为增量 进行组内直接插入排序 关键问题 1 的解决方法 关键问题 2 的解决方法 在每个子序列中 待插入记录和同一子序列中的前一个记录比较 在插入记录r i 时 自r i d 起往前跳跃式 跳跃幅度为d 搜索待插入位置 并且r 0 只是暂存单元 不是哨兵 当搜索位置 0 表示插入位置已找到 在搜索过程中 记录后移也是跳跃d个位置 在整个序列中 前d个记录分别是d个子序列中的第一个记录 所以从第d 1个记录开始进行插入 解决问题 2 的算法 for i d 1 i0 时间性能 对希尔排序算法的时间性能的分析是一个复杂的问题 因为它是所取 增量 的函数 而到目前为止尚未有人求得一种最好的增量序列 有人在大量实验的基础上指出 希尔排序的时间性能在O n2 和O nlog2n 之间 当n在某个特定范围内 希尔排序所需的比较次数和记录的移动次数约为n1 3 交换排序 主要思想 在待排序列中选两个记录 将它们的关键码相比较 如果反序 即排列顺序与排序后的次序正好相反 则交换它们的存储位置 排序技术 8 3 1起泡排序 基本思想 两两比较相邻记录关键码 如果反序则交换 直到没有反序的记录为止 65 65 55 起泡排序过程示例 65 55 50 具体的排序过程 将整个待排序的记录序列划分成有序区和无序区 初始状态有序区为空 无序区包括所有待排序的记录 对无序区从前向后依次将相邻记录的关键码进行比较 若反序则交换 从而使得关键码小的记录向前移 关键码大的记录向后移 像水中的汽泡 体积大的先浮上来 重复执行 直到无序区中没有反序的记录 需解决的关键问题 在一趟起泡排序中 若有多个记录位于最终位置 应如何记载 如何确定起泡排序的范围 使得已经位于最终位置的记录不参与下一趟排序 如何判别起泡排序的结束 问题 的解决 设变量exchange记载记录交换的位置 则一趟排序后 exchange记载的一定是这一趟排序中记录的最后一次交换的位置 且从此位置以后的所有记录均已经有序 算法描述为 if r j r j 1 r j r j 1 exchange j 问题 的解决 设bound位置的记录是无序区的最后一个记录 则每趟起泡排序的范围是r 1 r bound 而在一趟排序后 从exchange位置之后的记录一定是有序的 所以bound exchange 算法描述为 bound exchange for j 1 jr j 1 r j r j 1 exchange j 问题 的解决 在每一趟起泡排序之前 令exchange的初值为0 在以后的排序过程中 只要有记录交换 exchange的值就会大于0 这样 在一趟比较完毕 就可以通过exchange的值是否为0来判别是否有记录交换 从而判别整个起泡排序的结束 voidBubbleSort intr intn exchange n while exchange bound exchange exchange 0 for j 1 jr j 1 r j r j 1 exchange j 起泡排序算法 时间性能分析 最好情况 算法只执行一趟 进行了n 1次关键码的比较 不需要移动记录 时间复杂度为O n 最坏情况 每趟只浮出一个当前无序序列中最大的记录 故算法执行n 1趟 第i 1 i n 趟做了n i次关键码的比较 执行了n i次记录的交换 时间复杂度为O n2 平均情况 时间复杂度为O n2 8 3 2快速排序 改进的着眼点是 在起泡排序中 记录的比较和移动是在相邻单元中进行的 记录每次交换只能上移或下移一个单元 因而总的比较次数和移动次数较多 在快速排序中 记录的比较和移动是从两端向中间进行的 关键码较大的记录一次就能从前面移动到后面的单元 关键码较小的记录一次就能从后面移动到前面的单元 记录每次移动的距离较远 从而减少了总的比较次数和移动次数 快速排序的基本思想 首先选一个轴值 即比较的基准 通过一趟排序将待排序记录分割成独立的两部分 前一部分记录的关键码均小于轴值 后一部分记录的关键码均大于或等于轴值 然后分别对这两部分重复上述方法 直到整个序列有序 需解决的关键问题 如何选择轴值 在每个子序列内如何实现快速排序 通常叫做一次划分 如何处理分区得到的两个待排序子序列 如何判别快速排序的结束 一次划分示例 问题 的解决 选择轴值的方法 1 使用第一个记录的关键码 2 选取序列中间记录的关键码 3 比较序列中第一个记录 最后一个记录和中间记录的关键码 取关键码居中的作为轴值并调换到第一个记录的位置 4 随机选取轴值 问题 的解决 设待划分的序列是r s r t 设参数i j分别指向子序列左 右两端的下标s和t 令r s 为轴值 1 j从后向前扫描 直到r j r i 将r j 移动到r i 的位置 使关键码小 同轴值相比 的记录移动到前面去 2 i从前向后扫描 直到r i r j 将r i 移动到r j 的位置 使关键码大 同轴值比较 的记录移动到后面去 3 重复上述过程 直到i j 即指向同一位置 整个快速排序的过程可递归进行 若待排序列中只有一个记录 显然已有序 否则进行一趟快速排序后 再分别对分割所得的两个子序列进行快速排序 即递归处理 问题 的解决 13 27 50 38 49 55 j i i j 13 65 27 50 38 49 55 快速排序的执行过程 65 voidquickSort intr intfirst intend 在序列first end中递归地进行快速排序if first end pivotpos partition r first end quickSort r first pivotpos 1 quickSort r pivotpos 1 end 快速排序算法 快速排序的时间性能分析 快速排序的趟数取决于递归的深度 最好情况 每一次划分对一个记录定位后 该记录的左侧子表与右侧子表的长度相同 为O nlog2n 最坏情况 正序或逆序 每次划分只得到一个比上一次划分少一个记录的子序列 另一个子序列为空 为O n2 平均情况 为O nlog2n 081621252849 012345 初始 1621252849 08 21252849 0816 252849 081621 2849 08162125 49 0816212528 i 1 i 2 i 3 i 4 i 5 快速排序退化的例子 选择排序 排序技术 主要思想 每趟排序在当前待排序序列中选出关键码最小的记录 添加到有序序列中 选出最小记录 有序序列 无序序列 一趟排序后 8 4 1简单选择排序 基本思想 第i趟在n i 1 i 1 2 3 n 1 个记录中选取关键码最小的记录作为有序序列中的第i个记录 需解决的关键问题 如何在待排序序列中选出关键码最小的记录 如何确定待排序序列中关键码最小的记录在有序序列中的位置 简单选择排序示例 最小者08交换21 08 最小者16交换25 16 最小者21交换49 21 08 16 21 简单选择排序示例 最小者25交换25 28 25 将整个记录序列划分为有序区和无序区 初始状态有序区为空 无序区含有待排序的所有记录 在无序区中选取关键码最小的记录 将它与无序区中的第一个记录交换 使得有序区扩展了一个记录 而无序区减少了一个记录 不断重复 直到无序区只剩下一个记录为止 此时所有的记录已经按关键码从小到大的顺序排列就位 具体实现过程 问题 的解决 设置一个整型变量index 用于记录在一趟比较的过程中关键码最小的记录位置 算法描述为 index i for j i 1 j n j if r j r index index j 问题 的解决 第i趟简单选择排序的待排序区间是r i r n 则r i 是无序区第一个记录 所以 将index所记载的关键码最小的记录与r i 交换 算法描述为 if index i r i r index voidselectSort intr intn for i 1 ir index 简单选择排序算法 简单选择排序时间性能分析 移动次数 最好情况 正序 0次 最坏情况 反序 3 n 1 次 比较次数 无论记录的初始排列如何 所需进行的键值的比较次数相同 第i趟排序需进行n i次键值的比较 而简单选择排序需进行n 1趟排序 则总的比较次数为 O n2 需一个辅助空间 是一种稳定的排序算法 8 4 2堆排序 改进的着眼点 如何减少关键码间的比较次数 若能利用每趟比较后的结果 也就是在找出键值最小记录的同时 也找出键值较小的记录 则可减少后面的选择中所用的比较次数 从而提高整个排序过程的效率 堆的定义 堆是具有下列性质的完全二叉树 每个结点的值都小于或等于其左右孩子结点的值 称为小根堆 或每个结点的值都大于或等于其左右孩子结点的值 称为大根堆 堆的根结点一定是所有结点的最小者 将堆用顺序存储结构来存储 则堆对应一组序列 堆的示例 18291940323622605038 堆排序的基本思想 首先将待排序的记录序列构造成一个堆 此时 选出了堆中所有记录的最小者 然后将它从堆中移走 并将剩余的记录再调整成堆 这样又找出了次小的记录 以此类推 直到堆中只有一个记录为止 每个记录出堆的顺序就是一个有序序列 需解决的关键问题 如何由一个无序序列建成一个堆 即初始建堆 如何处理堆顶记录 如何调整剩余记录 成为一个新的堆 即重建堆 堆调整的问题 在一棵完全二叉树中 根结点的左右子树均是堆 如何调整根结点 使整个完全二叉树成为一个堆 筛选法建堆 voidsift intr intk intm 设当前要筛选的结点的编号为k 堆中最后一个结点的编号为mi k j 2 i temp r i 将筛选记录暂存while jr j 1 j if r i r j break else r i r j i j j 2 i r i temp 将筛选记录移到正确位置 初始建堆 21 25 28 49 16 08 1 2 3 4 5 6 i 21 25 28 16 08 49 i 21 16 28 08 25 49 i 08 16 28 25 21 49 08 16 28 25 21 49 49 16 28 25 21 08 16 25 28 49 21 08 输出堆顶重建堆 堆排序算法 voidheapSort intr intn for i n 2 i 1 i 初建堆sift r i n for i 1 i n i 移走堆顶重建堆 r 1 r n i 1 sift r 1 n i 性能分析 初始建堆需要O n 时间 第i次取堆顶记录重建堆需要用O log2i 时间 并且需要取n 1次堆顶记录 因此整个时间复杂度为O nlog2n 这是堆排序的最好 最坏和平均的时间代价 8 5归并排序 归并排序的主要思想是 将若干有序段逐步归并 最终归并为一个有序段 二路归并排序的基本思想是 将一个具有n个待排序记录的序列看成是n个长度为1的有序序列 然后进行两两归并 得到n 2个长度为2的有序序列 再进行两两归并 得到n 4个长度为4的有序序列 直至得到一个长度为n的有序序列为止 需解决的关键问题 如何构造初始有序表 如何将两个有序表合成一个有序表 怎样完成一趟归并 如何控制二路归并的结束 二路归并排序示例 6020315445565 问题 的解决 假设初始序列含有n个记录 则可将整个序列看成是长度为1个记录的n个有序表 问题 的解决 设两个相邻的有序表r s r m 和r m 1 r t 将这两个有序表合成一个有序表r1 s r1 t 5203160 445565 5203144556065 i j k 有序表合成一个有序表算法 voidmerge intr intr1 ints intm intt i s j m 1 k s while i m 在一趟归并中 除最后一个有序表外 其它有序表中记录的个数相同 我们用长度h表示 现在的任务是把若干个相邻的长度为h的有序表和最后一个长度有可能小于h的有序表进行两两归并 把结果存放到r1 1 r1 n 中 设参数i指向待归并段的第一个记录 归并的步长是2h 问题 的解决 在归并过程中 有以下三种情况 若i n 2h 1 则表示相邻两个有序表的长度均为h 执行一次归并 完成后i加2h 准备进行下一次归并 若i n h 1 则表示仍有两个相邻有序表 一个长度为h 另一个长度小于h 则执行两个有序表的归并 完成后退出一趟归并 若i n h 1 则表明只剩下一个有序表 直接将该有序表送到r1的相应位置 完成后退出一趟归并 voidmergePass intr intr1 intn inth i 1 while i n 2h 1 merge r r1 i i h 1 i 2 h 1 i 2 h if i n h 1 merge r r1 i i h 1 n elsefor k i k n k r1 k r k 一趟归并排序算法 问题 的解决 开始时 有序表的长度h 1 结束时 有序表的长度为n 有序表的长度来控制排序工作的结束 voidmergeSort intr intr1 intn h 1 while h n mergePass r r1 h h 2 h

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论