知识点插入排序.PPT

知识点插入排序

《数据结构》 第十章 内部排序 第十章 内部排序 例:序列为 {49, 38, 65,97,76,13,27,49} {(49),38,65,97,76,13,27,49} i=2 {(38,49),65,97,76,13,27,49} i=3 {(38,49,65),97,76,13,27,49} i=4 {(38,49,65,97),76,13,27,49} i=5 {(38,49,65,76,97),13,27,49} i=6 {(13,38,49,65,76,97),27,49} i=7 {(13,27,38,49,65,76,97),49} i=8 {(13,27,38,49,49,65,76,97)} 基本思想:将整个待排序记录分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列中的记录基本有序时,对全体记录进行直接插入排序。 需解决的关键问题? (1)应如何分割待排序记录,才能保证整个序列逐步向基本有序发展? (2)子序列内如何进行直接插入排序? 分割待排序记录的目的? 1. 减少待排序记录个数; 2. 使整个序列向基本有序发展。 基本有序:例如{1, 2, 8, 4, 5, 6, 7, 3, 9}; 局部有序:例如{6, 7, 8, 9, 1, 2, 3, 4, 5}。 局部有序不能提高直接插入排序算法的时间性能。 启示? 子序列的构成不能是简单地“逐段分割”,而是将相距某个“增量”的记录组成一个子序列。 解决方法: 将相隔某个“增量”的记录组成一个子序列。 增量应如何取? 希尔最早提出的方法是d1=n/2,di+1=di/2。 解决方法: (1) 在插入记录r[i]时,自r[i-d]起往前跳跃式(跳跃幅度为d)搜索待插入位置,并且r[0]只是暂存单元,不是哨兵。当搜索位置<0,表示插入位置已找到。 (2) 在搜索过程中,记录后移也是跳跃d个位置。 (3) 在整个序列中,前d个记录分别是d个子序列中的第一个记录,所以从第d+1个记录开始进行插入。 例:关键字序列 T=(49,38,65,97, 76, 13, 27, 49*,55, 04),请写出希尔排序的具体实现过程。 最坏的情况:先移到哨所里,所以i=2时,移了3次 插入位置high+1 或 low 当前i-1个元素已有序 在R[1..i-1]中查找R[i]的插入位置 J为插入位置的前驱位置(下标) K为插入位置的后继位置(下标) 当前i-1个元素已有序 在R[1..i-1]中查找R[i]的插入位置 J为插入位置的前驱位置(下标) K为插入位置的后继位置(下标) 当前i-1个元素已有序 在R[1..i-1]中查找R[i]的插入位置 J为插入位置的前驱位置(下标) K为插入位置的后继位置(下标) { m = (low + high) / 2; // 折半 if(L.r[0].key L.r[m].key) high = m-1; // 小于插入点在低半区 else low = m + 1; // 其他插入点在高半区 } for (j = i-1;j = high+1; --j) L.r[j+1] = L.r[j]; // 记录后移 L.r[high+1] =L.r[0]; // 插入 print(*L); } } 算法10.2 P267 对顺序表L作折半插入排序-(2) 算法分析 折半插入排序只能减少排序过程中关键字比较的时间,并不能减少记录移动的时间,因此折半插入排序的时间复杂度仍为O(n )。 2 为了减少在排序过程中进行的 “移动”记录的操作,必须改变排序过程中采用的存储结构。利用静态链表进行排序,并在排序完成之后,一次性地调整各个记录相互之间的位置,即将每个记录都调整到它们所应该在的位置上。 3、表插入排序 (基于链表存储) 静态链表类型说明如下: #define SIZE 100 //静态链表容量 typedef struct { RcdType rc; //记录项 int next; //指针项 }SLNode; //表结点类型 typedef struct{ SLNode r[SIZE]; //0号单元为表头结点 int length; //链表当前长度 }SLinkListType; //静态链表类型 for ( j=0, k = SL[0].next; SL[i].key= S

文档评论(0)

1亿VIP精品文档

相关文档