资源预览内容
第1页 / 共82页
第2页 / 共82页
第3页 / 共82页
第4页 / 共82页
第5页 / 共82页
第6页 / 共82页
第7页 / 共82页
第8页 / 共82页
第9页 / 共82页
第10页 / 共82页
亲,该文档总共82页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
数据结构课程的内容 10 1概述10 2插入排序10 3交换排序10 4选择排序10 5归并排序10 6基数排序 第10章内部排序 10 1概述 1 什么是排序 将一组杂乱无章的数据按一定的规律顺次排列起来 2 排序的目的是什么 存放在数据表中 按关键字排序 便于查找 10 1概述 3 排序算法的好坏如何衡量 时间效率 排序速度 即排序所花费的全部比较次数 空间效率 占内存辅助空间的大小若排序算法所需的辅助空间不依赖问题的规模n 即空间复杂度是O 1 则称排序方法是就地排序 否则是非就地排序 稳定性 若两个记录A和B的关键字值相等 但排序后A B的先后次序保持不变 则称这种排序算法是稳定的 4 什么叫内部排序 什么叫外部排序 若待排序记录都在内存中 称为内部排序 内部排序基本操作有两种 比较两个关键字的大小 比不可少的操作 存储位置的移动 若待排序记录一部分在内存 一部分在外存 则称为外部排序 注 外部排序时 要将数据分批调入内存来排序 中间结果还要及时放入外存 显然外部排序要复杂得多 5 待排序记录在内存中怎样存储和处理 处理方式 顺序排序 数据间的逻辑顺序关系通过其物理存储位置的相邻来体现 排序时直接移动记录 适合数据较少的情况 链表排序 数据间的逻辑顺序关系通过结点中的指针体现 排序时只修改指针 不移动数据 地址排序 数据存储在一段连续地址的空间 构造一个辅助表保持各数据的存放地址 指针 排序时先修改辅助表中的地址 最后再移动记录 适合数据较多的情况 注 大多数排序算法都是针对顺序表结构的 便于直接移动元素 6 顺序存储 顺序表 的抽象数据类型如何表示 Typedefstruct 定义每个记录 数据元素 的结构KeyTypekey 关键字InfoTypeotherinfo 其它数据项 RecordType Typedefstruct 定义顺序表的结构RecordTyper MAXSIZE 1 存储顺序表的向量 r 0 一般作哨兵或缓冲区intlength 顺序表的长度 SqList defineMAXSIZE20 设记录不超过20个typedefintKeyType 设关键字为整型量 int型 7 内部排序的算法有哪些 按排序的规则不同 可分为5类 插入排序交换排序 重点是快速排序 选择排序归并排序基数排序 d 关键字的位数 长度 按排序算法的时间复杂度不同 可分为3类 简单的排序算法 时间效率低 O n2 先进的排序算法 时间效率高 O nlog2n 基数排序算法 时间效率高 O d n 10 2插入排序 插入排序的基本思想是 插入排序有多种具体实现算法 1 直接插入排序2 折半插入排序3 2路插入排序4 希尔排序 每步将一个待排序的对象 按其关键码大小 插入到前面已经排好序的一组对象的适当位置上 直到对象全部插入为止 简言之 边插入边排序 保证子序列中随时都是排好序的 1 直接插入排序 新元素插入到哪里 例1 关键字序列T 13 6 3 31 9 27 5 11 请写出直接插入排序的中间过程序列 13 6 3 31 9 27 5 11 6 13 3 31 9 27 5 11 3 6 13 31 9 27 5 11 3 6 13 31 9 27 5 11 3 6 9 13 31 27 5 11 3 6 9 13 27 31 5 11 3 5 6 9 13 27 31 11 3 5 6 9 11 13 27 31 在已形成的有序表中线性查找 并在适当位置插入 把原来位置上的元素向后顺移 最简单的排序法 例2 关键字序列T 21 25 49 25 16 08 请写出直接插入排序的具体实现过程 表示后一个25 i 1 21 i 2 i 3 i 5 i 4 i 6 25 25 25 49 49 49 25 49 16 16 08 49 解 假设该序列已存入一维数组V 7 中 将V 0 作为缓冲或暂存单元 Temp 则程序执行过程为 初态 16 25 21 16 完成 时间效率 O n2 因为在最坏情况下 所有元素的比较次数总和为 0 1 n 1 O n2 其他情况下还要加上移动元素的次数 空间效率 O 1 因为仅占用1个缓冲单元算法的稳定性 稳定 因为25 排序后仍然在25的后面 对应程序参见教材P265 VoidInsertSort SqList 插入到正确位置 InsertSort 不需要增加辅助空间若设待排序的对象个数为n 则算法需要进行n 1次插入 最好情况下 排序前对象已经按关键码大小从小到大有序 每趟只需与前面的有序对象序列的最后一个对象的关键码比较1次 对象不需要移动 因此 总的关键码比较次数为n 1 直接插入排序的算法分析 最坏情况下 第i趟插入时 第i个对象必须与前面i 1个对象都做关键码比较 并且每做1次比较就要做1次数据移动 则总的关键码比较次数KCN和对象移动次数RMN分别为 若待排序对象序列中出现各种可能排列的概率相同 则可取上述最好情况和最坏情况的平均情况 在平均情况下的关键码比较次数和对象移动次数约为n2 4 因此 直接插入排序的时间复杂度为o n2 直接插入排序是一种稳定的排序方法 2 折半插入排序 优点 比较的次数大大减少 时间效率 虽然比较次数大大减少 可惜移动次数并未减少 所以排序效率仍为O n2 空间效率 O 1 稳定性 稳定对应程序见教材P267 仅用于顺序表 新元素插入到哪里 在已形成的有序表中折半查找 并在适当位置插入 把原来位置上的元素向后顺移 VoidBInsertSort SqList L 折半插入排序 for i 2 i high 1 j L r j 1 L r j 记录后移L r high 1 L r 0 插入 for BInsertSort 初始 i 2 i 2 i 2 i 2 初始 i 8 i 8 i 8 初始 i 8 i 8 i 8 i 8 初始 i 8 i 8 i 8 i 8 折半插入排序的算法分析 折半查找比顺序查找快 所以折半插入排序就平均性能来说比直接插入排序要快 在插入第i个对象时 需要经过 log2i 1次关键码比较 才能确定它应插入的位置 折半插入排序是一个稳定的排序方法 讨论 若记录是链表结构 用直接插入排序行否 折半插入排序呢 答 直接插入不仅可行 而且还无需移动元素 时间效率更高 但链表无法 折半 折半插入排序的改进 2 路插入排序见教材P267 1 基本思想 P267 2 举例 P268图10 2 3 算法分析 移动记录的次数约为n2 82 路插入排序只能减少移动记录的次数 而不能绝对避免移动记录 实现是借助循环向量 若希望在排序过程中不移动记录 只有改变存储结构 进行表插入排序 4 希尔 shell 排序 又称缩小增量排序 基本思想 先将整个待排记录序列分割成若干子序列 分别进行直接插入排序 待整个序列中的记录 基本有序 时 再对全体记录进行一次直接插入排序 技巧 子序列的构成不是简单地 逐段分割 而是将相隔某个增量dk的记录组成一个子序列 让增量dk逐趟缩短 例如依次取5 3 1 直到dk 1为止 优点 让关键字值小的元素能很快前移 且序列若基本有序时 再用直接插入排序处理 时间效率会高很多 38 例 关键字序列T 49 38 65 97 76 13 27 49 55 04 请写出希尔排序的具体实现过程 初态 第1趟 dk 5 第2趟 dk 3 第3趟 dk 1 49 13 13 49 38 27 65 49 97 55 76 04 27 38 65 49 97 55 13 55 76 04 55 13 27 04 27 04 49 49 49 49 76 38 76 65 65 97 97 13 27 04 49 76 97 算法分析 开始时dk的值较大 子序列中的对象较少 排序速度较快 随着排序进展 dk值逐渐变小 子序列中对象个数逐渐变多 由于前面工作的基础 大多数对象已基本有序 所以排序速度仍然很快 r i voidShellSort SqList L intdlta intt 按增量序列dlta 0 t 1 对顺序表L作Shell排序for k 0 k t k ShellSort L dlta k 增量为dlta k 的一趟插入排序 ShellSort 时间效率 空间效率 O 1 因为仅占用1个缓冲单元算法的稳定性 不稳定 因为49 排序后却到了49的前面 希尔排序算法 主程序 参见教材P272 O n1 25 O 1 6n1 25 经验公式 dk值依次装在dlta t 中 附 希尔排序算法分析 对特定的待排序对象序列 可以准确地估算关键码的比较次数和对象移动次数 但想要弄清关键码比较次数和对象移动次数与增量选择之间的依赖关系 并给出完整的数学分析 还没有人能够做到 Knuth利用大量的实验统计资料得出 当n很大时 关键码平均比较次数和对象平均移动次数大约在n1 25到1 6n1 25的范围内 这是在利用直接插入排序作为子序列排序方法的情况下得到的 voidShellInsert SqListj j dk r j dk r j r j dk r 0 希尔排序算法 其中某一趟的排序操作 参见教材P272 对顺序表L进行一趟增量为dk的Shell排序 dk为步长因子 开始将r i 插入有序增量子表 暂存在r 0 关键字较大的记录在子表中后移 在本趟结束时将r i 插入到正确位置 课堂练习 1 欲将序列 Q H C Y P A M S R D F X 中的关键码按字母升序重排 则初始步长为4的希尔排序一趟的结果是 答 原始序列 Q H C Y P A M S R D F Xshell一趟后 2 以关键字序列 256 301 751 129 937 863 742 694 076 438 为例 分别写出执行以下算法的各趟排序结束时 关键字序列的状态 并说明这些排序方法中 哪些易于在链表 包括各种单 双 循环链表 上实现 直接插入排序 希尔排序 取dk 5 3 1 答 显然 直接插入排序方法易于在链表上实现 但希尔排序方法因为是按增量选择记录 不易于在链表上实现 两种排序方法的中间状态分别描述如后 原始序列 256 301 751 129 937 863 742 694 076 438 256 301 751 129 937 863 742 694 076 438 256 301 751 129 937 863 742 694 076 438 129 256 301 751 937 863 742 694 076 438 129 256 301 751 937 863 742 694 076 438 129 256 301 751 863 937 742 694 076 438 129 256 301 742 751 863 937 694 076 438 129 256 301 694 742 751 863 937 076 438 076 129 256 301 694 742 751 863 937 438 076 129 256 301 438 694 742 751 863 937 直接插入排序 第1趟第2趟第3趟第4趟第5趟第6趟第7趟第8趟第9趟 原始序列 256 301 751 129 937 863 742 694 076 438 希尔排序 取dk 5 3 1 256 301 751 129 937 863 742 694 076 438 256 301 751 129 937 863 742 694 076 438 256 301 694 129 937 863 742 751 076 438 256 301 694 076 937 863 742 751 129 438 256 301 694 076 438 863 742 751 129 937 第1趟dk 5第2趟dk 3第3趟dk 1 256 301 694 076 438 863 742 751 129 937 256 301 694 076
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号