插入排序.ppt

上传人:啊飒飒 文档编号:11881097 上传时间:2021-10-11 格式:PPT 页数:47 大小:404KB
返回 下载 相关 举报
插入排序.ppt_第1页
第1页 / 共47页
插入排序.ppt_第2页
第2页 / 共47页
插入排序.ppt_第3页
第3页 / 共47页
插入排序.ppt_第4页
第4页 / 共47页
插入排序.ppt_第5页
第5页 / 共47页
点击查看更多>>
资源描述

《插入排序.ppt》由会员分享,可在线阅读,更多相关《插入排序.ppt(47页珍藏版)》请在三一文库上搜索。

1、第九章 排序 9.1 概述 9.2 插入排序 9.3 交换排序 9.4 选择排序 9.5 归并排序 9.6 基数排序 9.7 各种内部排序的比较 9.1 概述 一、排序 定义将一个数据元素(或记录)的任意序列,重 新排列成一个按关键字有序的序列叫 二、排序分类 1.按待排序记录所在位置 内部排序:待排序记录存放在内存 外部排序:排序过程中需对外存进行访问的排序 2.按排序依据原则 插入排序:直接插入排序、折半插入排序、希尔排序 交换排序:冒泡排序、快速排序 选择排序:简单选择排序、堆排序 归并排序:2-路归并排序 基数排序 3、按排序所需工作量 简单的排序方法:T(n)=O(n) 先进的排序方

2、法:T(n)=O(logn) 基数排序:T(n)=O(d.n) 4、排序基本操作 比较两个关键字大小 将记录从一个位置移动到另一个位置 三、排序的稳定性 如果两个相同的关键字ki与关键字kj在排序之前其序 号为ij,在排完序后,这两个关键字的关后位置关系依 然为ij, 则认为排序是稳定的,反之认为是不稳定的。 9.2.1 直接插入排序 1.排序的思想: 排序过程:整个排序过程为n-1趟插入,即先将序列中 第1个记录看成是一个有序子序列,然后从第2个记录开始, 逐个进行插入,直至整个序列有序 9.2 9.2 插入排序插入排序 2.算法描述: void InsertSort(SqList i=L.

3、length;+i) if(LT(L.ri.key, L.ri-1.key) L.r0=L.ri; /监视哨 L.ri=L.ri-1; j=i-2; while(LT(L.r0.key,L.rj.key)j-;L.rj+1=L.rj; L.rj+1=L.r0; 例 49 38 65 97 76 13 27 i=2 38 (38 49) 65 97 76 13 27 i=3 65 (38 49 65) 97 76 13 27 i=4 97 (38 49 65 97) 76 13 27 i=5 76 (38 49 65 76 97) 13 27 i=6 13 (13 38 49 65 76 97)

4、 27 i=1 ( ) i=7 (13 38 49 65 76 97) 2727 jjjjjj 977665493827 (13 27 38 49 65 76 97)排序结果: 3.算法演示: T(n)=O(n) 4.算法评价: (1)时间复杂度 .若待排序记录按关键字从小到大排列(正序) 关键字比较次数: 记录移动次数: .若待排序记录按关键字从大到小排列(逆序) 关键字比较次数: 记录移动次数: .若待排序记录是随机的,取平均值 关键字比较次数: 记录移动次数: (2)空间复杂度:S(n)=O(1) 9.2.2 折半插入排序 l排序过程:用折半查找方法确定插入位置的排序叫 例 i=1 (3

5、0) 13 70 85 39 42 6 20 i=2 13 (13 30) 70 85 39 42 6 20 i=7 6 (6 13 30 39 42 70 85 ) 20 . i=8 20 (6 13 30 39 42 70 85 ) 20 sjm i=8 20 (6 13 30 39 42 70 85 ) 20 sjm i=8 20 (6 13 30 39 42 70 85 ) 20 sjm i=8 20 (6 13 30 39 42 70 85 ) 20 sj i=8 20 (6 13 20 30 39 42 70 85 ) 1、算法描述 2、算法评价 时间复杂度:T(n)=O(n) 空

6、间复杂度:S(n)=O(1) void BInsertSort(SqList i=L.length;+i) L.r0=L.ri; low=1; high=i-1; /已排序的序列 while(low=high+1;-j) L.rj+1=L.rj; /移动 L.rhigh+1=L.r0; /插入 /for /BInsertSort 9.2.3 希尔排序(缩小增量法) 1.排序思想: 先取一个正整数d1n,把所有相隔d1的记录放一组 ,组内进行直接插入排序;然后取d2d1,重复上述 分组和排序操作;直至di=1,即所有记录放进一个组 中排序为止 2. 算法描述: void ShellInsert(

7、SqList i0j-=dk)/移动 L.rj+dk=L.rj; L.rj+dk=L.r0; /插入 / if,for /ShellInsert void ShellSort(SqList kr2.key,则交换;然后 比较第二个记录与第三个记录;依次类推,直至第n-1 个记录和第n个记录比较为止第一趟冒泡排序,结 果关键字最大的记录被安置在最后一个记录上 (2)对前n-1个记录进行第二趟冒泡排序,结果使关键 字次大的记录被安置在第n-1个记录位置 (3)重复上述过程,直到“在一趟排序过程中没有进 行过交换记录的操作”为止 第i步1015781154212233 151515 8 2、冒泡排序

8、算法演示 排序前 1021223315781154 找第1个最大数 第1步1021223315781154 33153373383313315334 71415 找第 i 个最大数 从第 1个元素开始到第 i 个元素,把相邻两个元素进行比较,如 果前面的比后面的大,则交换两个元素,这样可以得使第 i 个元素 是最大的。算法如下: 让 j 从 1 到 i 变化,重复: 如果L.rj.keyL.rj+1.key ,则交换L.rj与L.rj+1 3.算法描述和实现 void BubbleSort(SqList for(i=1;i=n;i+) flag=FALSE; /交换标志 for(j=1;j=n

9、-i;j+) if(GT(L.rj.key,L.rj+1.key) /如果前面元素大于后面元素,则交换 temp=L.rj;L.rj=L.rj+1;L.rj+1=temp; flag=TRUE; /有交换 /if if(!flag) break; /如果无交换,则结束 /for /BubbleSort 4、算法评价 (1)时间复杂度 最好情况(正序) 比较次数:n-1 移动次数:0 最坏情况(逆序) 比较次数: 移动次数: (2)空间复杂度:S(n)=O(1) T(n)=O(n) 9.3.2 快速排序 1、基本思想:通过一趟排序,将待排序记录分割成独立的 三部分 (x1,x2,x3,.,xk-

10、1) xk (xk+1,xk+2,.,xn) 其中,xk比左边的所有元素都大,但比右边所有元素都小 。 2、排序过程:对rst中记录进行一趟快速排序,附 设两个指针i和j,设数组记录rp=rs,x=rp.key (1)初始时令i=s,j=t (2)首先从j所指位置向前搜索第一个关键字小于x的记录,并和 rp交换 (3)再从i所指位置起向后搜索,找到第一个关键字大于x的记录 ,和rp交换 (4)重复上述(2)、(3)两步,直至i=j为止 (5)再分别对两个子序列进行快速排序,直到每个子序列只含有 一个记录为止 例 初始关键字: 49 38 65 97 76 13 27 50 ij x ji 完成

11、一趟排序: ( 27 38 13) 49 (76 97 65 50) 分别进行快速排序: ( 13) 27 (38) 49 (50 65) 76 (97) 快速排序结束: 13 27 38 49 50 65 76 97 4927 i ji j ij 4965 j i 13 49 i j 4997 ij 3、算法描述及实现: int Patition(SqList /用子表第一个元素作分类 while(lowhigh) /从后往前走,如果x大于rhigh元素,则结束并交换 while(low=x) -high; swap(L.rlow,L.rhigh); /交换 /从前往后走,如果x小于rlow

12、元素,则结束并交换 while(lowhigh swap(L.rlow,L.rhigh); /交换 return low; /分类元素所在下标 void QuickSort(SqList QuickSort(SqList,low,m-1); QuickSort(SqList,m+1,high); 4、算法评价 (1)时间复杂度 最好情况(每次总是选到中间值作分类元素) T(n)=O(nlog2n) 最坏情况(每次总是选到最小或最大元素作分类元素) T(n)=O(n) (2)空间复杂度:需栈空间以实现递归 最坏情况:S(n)=O(n) 一般情况:S(n)=O(log2n) 9.4 选择排序 9.

13、4.1 简单选择排序 1、排序思想 (1)首先通过n-1次关键字比较,从n个记录中找出关键字 最小的记录,将它与第一个记录交换 (2)再通过n-2次比较,从剩余的n-1个记录中找出关键字 次小的记录,将它与第二个记录交换 (3)重复上述操作,共进行n-1趟排序后,排序结束 例初始: 49 38 65 97 76 13 27 k jjjjjj kk i=1 13 49 一趟: 13 38 65 97 76 49 27 i=2 kk jjjjj 2738 二趟: 13 27 65 97 76 49 38 三趟: 13 27 38 97 76 49 65 四趟: 13 27 38 49 76 97

14、65 五趟: 13 27 38 49 65 97 76 六趟: 13 27 38 49 65 76 97 排序结束: 13 27 38 49 65 76 97 2、算法演示 3、算法描述与实现 void SelectSort(SqList for(i=1;i=n;i+) p=SelectMinKey(L,i); /在i.n之间选择最小数下标 if(p!=i) swap(L.ri,L.rp); /for /selectsort int SelectMinKey(SqList for(k=i;k0;-i) /建堆 HeapAdjust(H,i,H.length); for(i=H.length;i

15、1;-i) swap(H.r1,H.ri HeapAdjust(H,1,i-1); /调整H.r1.i-1为最大堆 /HeapSort 例 含8个元素的无序序列(49,38,65,97,76,13,27,50) 49 6538 27137697 50 49 6538 27137650 97 49 1338 27657650 97 49 1338 27657650 97 13 2738 49657650 97 5、算法评价 (1)时间复杂度:最坏情况下T(n)=O(nlogn) (2)空间复杂度:S(n)=O(1) 4、调整堆算法描述 void HeapAdjust(HeapType j=2*s

16、; while(j=m) if(jm /找s的两个孩子的最大孩子 if(!LT(rc.key,H.rj.key) break; /如果双亲不大于最大孩子,则已经是堆,结束 H.rs=H.rj; /最大元素调到双亲 s=j; /以最大孩子作为新的子树,继续向下调整 j=2*s; /新子树s的孩子 /while /HeapAdjust 9.5 归并排序 1、归并 将两个或两个以上的有序表组合成一个新的有序 表,叫 2、2路归并排序 (1)排序思想 设初始序列含有n个记录,则可看成n个有序的子序列, 每个子序列长度为1 两两合并,得到n/2个长度为2或1的有序子序列 再两两合并,如此重复,直至得到一

17、个长度为n的有 序序列为止 例 初始关键字: 49 38 65 97 76 13 27 一趟归并后: 38 49 65 97 13 76 27 二趟归并后: 38 49 65 97 13 27 76 三趟归并后: 13 27 38 49 65 76 97 3、算法描述 4、算法评价 (1)时间复杂度 : T(n)=O(nlog2n) (2)空间复杂度 :S(n)=O(n) void Merge(RcdType SR,RcdType k=i; /SRi.m与SRm+1,n合并,合并后放入TRi.n中 while(i=m else TRk+=SRj+; if(i=m)TRk.n=SRi.m; /如

18、果第一个数组未完,其余放入后面 if(j=n) TRk.n=SRj.n; /如果第二个数组未完,其余放入后面 /Merge /将SRs.t归并为TR1s.t void MSort(RcdType SR,RcdType else m=(s+t)/2; MSort(SR,TR2,s,m); /将SRs.m归并到TR2s.m MSort(SR,TR2,m+1,t);/将SRm+1.t归并到TRm+1.t中 Merge(TR2,TR1,s,m,t);/将TR2s.t归并入TR1中 9.6 基数排序 9.6.1 多关键字排序 1.定义 例 对52张扑克牌按以下次序排序: 23A23A 23A23A 两个

19、关键字:花色( ) 面值(23A) 并且“花色”地位高于“面值” 2、多关键字排序方法 (1)最高位优先法(MSD):先对最高位关键字k1(如花色)排序,将序列分 成若干子序列,每个子序列有相同的k1值;然后让每个子序列对次关键 字k2(如面值)排序,又分成若干更小的子序列;依次重复,直至就每 个子序列对最低位关键字kd排序;最后将所有子序列依次连接在一起成 为一个有序序列 (2)最低位优先法(LSD):从最低位关键字kd起进 行排序,然后再对高一位的关键字排序, 依次重复,直至对最高位关键字k1排序后,便 成为一个有序序列 (3)MSD与LSD不同特点 l按MSD排序,必须将序列逐层分割成若

20、干子序列,然 后对各子序列分别排序 l按LSD排序,不必分成子序列,对每个关键字都是整 个序列参加排序;并且可不通过关键字比较,而通 过若干次分配与收集实现排序 9.6.2 链式基数排序 l基数排序:借助“分配”和“收集”对单逻辑关键 字进行排序的一种方法 l链式基数排序:用链表作存储结构的基数排序 1、链式基数排序步骤 (1)设置10个队列,fi和ei分别为第i个队列的 头指针和尾指针 (2)第一趟分配对最低位关键字(个位)进行,改 变记录的指针值,将链表中记录分配至10个链队 列中,每个队列记录的关键字的个位相同 (3)第一趟收集是改变所有非空队列的队尾记录的 指针域,令其指向下一个非空队

21、列的队头记录, 重新将10个队列链成一个链表 (3)重复上述两步,进行第二趟、第三趟分配和收 集,分别对十位、百位进行,最后得到一个有序 序列 例 初始状态: 278109063930589184505269008083 109 589 269 278063930 083 184505 008 e0e1e2e3e4e5e6e7e8e9 f0f1f2f3f4f5f6f7f8f9 一趟分配 930063083184505278008109589269 一趟收集: 505008109930063269278083184589 二趟收集: 083 184 589 063505 269 930 e0e1

22、e2e3e4e5e6e7e8e9 f0f1f2f3f4f5f6f7f8f9 二趟分配 008 109 278 930063083184505278008109589269 一趟收集: 008063083109184269278505589930 三趟收集: 109008 184 930 e0e1e2e3e4e5e6e7e8e9 f0f1f2f3f4f5f6f7f8f9 三趟分配 063 083 269 278 505 589 505008109930063269278083184589 二趟收集: 2、算法描述与实现 /分配算法,对第i个关键字进行分配 void Distribute(SLCe

23、ll jRadix;+j) fj=0; p=r0.next; while(p!=0) j=ord(rp.keysi); /将记录中第i个关键字映射到0.RADIX-1,即第i个关键字对应队列j if(!fj) fj=p; /如果是空队,直接赋值 else rej.next=p; /放在队尾元素的后面,rej表示队列j的队尾元素一 ej=p; /修改队列j的队尾指针 p=rp.next; /取p元素的下一个元素 /while /Distribute void Collect(SLCell fj!=0;j=succ(j); /找第一非空子表 r0.next=fj;t=ej; while(jRADI

24、X) for(j=succ(j);jRADIX-1j=succ(j); if(f(j)!=0) rt.next=fj;t=ej; /while rt.next=0; /Collect 3、算法评价 (1)时间复杂度: 分配:T(n)=O(n) 收集:T(n)=O(rd) T(n)=O(d(n+rd) 其中:n记录数 d关键字数 rd关键字取值范围 (2)空间复杂度:S(n)=2rd个队列指针+n个指针域 空间 初始状态: 1 2781090639305891845052690080830 2345678910 f0=0 e0=0 f1=0 e1=0 f2=0 e2=0 f3=0 e3=0 f4

25、=0 e4=0 f5=0 e5=0 f6=0 e6=0 f7=0 e7=0 f8=0 e8=0 f9=0 e9=0 11 2 2 33 44 5 6 6 77 8 9 10 4 9300630831845052780081095892690 3106719258 f0=0 e0=0 f1=0 e1=0 f2=0 e2=0 f3=0 e3=0 f4=0 e4=0 f5=0 e5=0 f6=0 e6=0 f7=0 e7=0 f8=0 e8=0 f9=0 e9=0 1 3 44 7 7 9 10 4 9300630831845052780081095892690 3106719258 一趟收集: 3

26、 10 1 6 2 5 8 7 5050081099300632692780831845890 9243811065 二趟收集: 7 5050081099300632692780831845890 9243811065 二趟收集: f0=0 e0=0 f1=0 e1=0 f2=0 e2=0 f3=0 e3=0 f4=0 e4=0 f5=0 e5=0 f6=0 e6=0 f7=0 e7=0 f8=0 e8=0 f9=0 e9=044 7 9 2 8 7 9 2 8 9 0080630831091842692785055899300 3102681754 三趟收集: 3 1 10 6 5 总 结 要求: 掌 握:插入算法、选择算法、冒泡算法 基本掌握:快速排序,堆排序,归并排序 希尔排序 理解:基数排序,折半排序 要素:排序思想,时间复杂度,算法稳定性

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 科普知识


经营许可证编号:宁ICP备18001539号-1