排序算法一览.doc

上传人:marr****208 文档编号:156943246 上传时间:2020-12-20 格式:DOC 页数:18 大小:121KB
返回 下载 相关 举报
排序算法一览.doc_第1页
第1页 / 共18页
排序算法一览.doc_第2页
第2页 / 共18页
排序算法一览.doc_第3页
第3页 / 共18页
排序算法一览.doc_第4页
第4页 / 共18页
排序算法一览.doc_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《排序算法一览.doc》由会员分享,可在线阅读,更多相关《排序算法一览.doc(18页珍藏版)》请在金锄头文库上搜索。

1、排序算法一览 第10章 排序10.1基本概念排序(Sorting)是计算机程序设计中的一种重要操作,其功能是对一个数据元素集合或序列重新排列成一个按数据元素某个项值有序的序列。作为排序依据的数据项称为“排序码”,也即数据元素的关键码。为了便于查找,通常希望计算机中的数据表是按关键码有序的。如有序表的折半查找,查找效率较高。还有,二叉排序树、B-树和B+树的构造过程就是一个排序过程。若关键码是主关键码,则对于任意待排序序列,经排序后得到的结果是唯一的;若关键码是次关键码,排序结果可能不唯一,这是因为具有相同关键码的数据元素,这些元素在排序结果中,它们之间的的位置关系与排序前不能保持。若对任意的数

2、据元素序列,使用某个排序方法,对它按关键码进行排序:若相同关键码元素间的位置关系,排序前与排序后保持一致,称此排序方法是稳定的;而不能保持一致的排序方法则称为不稳定的。 排序分为两类:内排序和外排序。内排序:指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列。外排序:指排序过程中还需访问外存储器,足够大的元素序列,因不能完全放入内存,只能使用外排序。10.2插入排序10.2.1直接插入排序设有n个记录,存放在数组r中,重新安排记录在数组中的存放顺序,使得按关键码有序。即r1.keyr2.keyrn.key先来看看向有序表中插入一个记录的方法:设,r1.keyr2.keyrj-1.

3、key,将rj插入,重新安排存放顺序,使得r1.keyr2.keyrj.key,得到新的有序表,记录数增。【算法10.1】 r0=rj; /rj送r0中,使rj为待插入记录空位i=j-1; /从第i个记录向前测试插入位置,用r0为辅助单元, 可免去测试i1。 若r0.keyri.key,转。 /插入位置确定 若r0.key ri.key时,ri+1=ri;i=i-1;转。 /调整待插入位置 ri+1=r0;结束。 /存放待插入记录【例10.1】向有序表中插入一个记录的过程如下:r1 r2 r3 r4 r5 存储单元2 10 18 25 9 将r5插入四个记录的有序表中,j=5r0=rj;i=j

4、-1; 初始化,设置待插入位置2 10 18 25 ri+1为待插入位置i=4,r0 ri,ri+1=ri;i-; 调整待插入位置2 10 18 25 i=3,r0 ri,ri+1=ri;i-; 调整待插入位置2 10 18 25 i=2,r0 ri,ri+1=ri;i-; 调整待插入位置2 10 18 25 i=1,r0 ri,ri+1=r0; 插入位置确定,向空位填入插入记录2 9 10 18 25 向有序表中插入一个记录的过程结束直接插入排序方法:仅有一个记录的表总是有序的,因此,对n个记录的表,可从第二个记录开始直到第n个记录,逐个向有序表中进行插入操作,从而得到n个记录按关键码有序的

5、表。【算法10.2】void InsertSort(S_TBL &p) for(i=2;ilength;i+)if(p-elemi.key elemi-1.key) /*小于时,需将elemi插入有序表*/ p-elem0.key=p-elemi.key; /*为统一算法设置监测*/for(j=i-1;p-elem0.key elemj.key;j-)p-elemj+1.key=p-elemj.key; /*记录后移*/p-elemj+1.key=p-elem0.key; /*插入到正确位置*/【效率分析】空间效率:仅用了一个辅助单元。时间效率:向有序表中逐个插入记录的操作,进行了n-1趟,每

6、趟操作分为比较关键码和移动记录,而比较的次数和移动记录的次数取决于待排序列按关键码的初始排列。最好情况下:即待排序列已按关键码有序,每趟操作只需1次比较2次移动。总比较次数=n-1次总移动次数=2(n-1)次最坏情况下:即第j趟操作,插入记录需要同前面的j个记录进行j次关键码比较,移动记录的次数为j+2次。平均情况下:即第j趟操作,插入记录大约同前面的j/2个记录进行关键码比较,移动记录的次数为j/2+2次。由此,直接插入排序的时间复杂度为O(n2)。是一个稳定的排序方法。10.2.2折半插入排序直接插入排序的基本操作是向有序表中插入一个记录,插入位置的确定通过对有序表中记录按关键码逐个比较得

7、到的。平均情况下总比较次数约为n2/4。既然是在有序表中确定插入位置,可以不断二分有序表来确定插入位置,即一次比较,通过待插入记录与有序表居中的记录按关键码比较,将有序表一分为二,下次比较在其中一个有序子表中进行,将子表又一分为二。这样继续下去,直到要比较的子表中只有一个记录时,比较一次便确定了插入位置。二分判定有序表插入位置方法: low=1;high=j-1;r0=rj; / 有序表长度为j-1,第j个记录为待插入记录/设置有序表区间,待插入记录送辅助单元 若lowhigh,得到插入位置,转 lowhigh,m=(low+high)/2; / 取表的中点,并将表一分为二,确定待插入区间*/

8、 若r0.keyrm.key,high=m-1; /插入位置在低半区否则,low=m+1; / 插入位置在高半区转 high+1即为待插入位置,从j-1到high+1的记录,逐个后移,rhigh+1=r0;放置待插入记录。【算法10.3】void InsertSort(S_TBL *s) /* 对顺序表s作折半插入排序 */for(i=2;ilength;i+) s-elem0=s-elemi; /* 保存待插入元素 */low=i;high=i-1; /* 设置初始区间 */while(lowelem0.keys-elemmid.key)low=mid+1; /* 插入位置在高半区中 */e

9、lse high=mid-1; /* 插入位置在低半区中 */* while */for(j=i-1;j=high+1;j-) /* high+1为插入位置 */s-elemj+1=s-elemj; /* 后移元素,留出插入空位 */s-elemhigh+1=s-elem0; /* 将元素插入 */* for */* InsertSort */【时间效率】确定插入位置所进行的折半查找,关键码的比较次数至多为 ,次,移动记录的次数和直接插入排序相同,故时间复杂度仍为O(n2)。是一个稳定的排序方法。10.2.3表插入排序直接插入排序、折半插入排序均要大量移动记录,时间开销大。若要不移动记录完成排

10、序,需要改变存储结构,进行表插入排序。所谓表插入排序,就是通过链接指针,按关键码的大小,实现从小到大的链接过程,为此需增设一个指针项。操作方法与直接插入排序类似,所不同的是直接插入排序要移动记录,而表插入排序是修改链接指针。用静态链表来说明。#define SIZE 200typedef structElemType elem; /*元素类型*/int next; /*指针项*/NodeType; /*表结点类型*/typedef structNodeType rSIZE; /*静态链表*/int length; /*表长度*/L_TBL; /*静态链表类型*/假设数据元素已存储在链表中,且0

11、号单元作为头结点,不移动记录而只是改变链指针域,将记录按关键码建为一个有序链表。首先,设置空的循环链表,即头结点指针域置0,并在头结点数据域中存放比所有记录关键码都大的整数。接下来,逐个结点向链表中插入即可。【例10.2】表插入排序示例MAXINT 49 38 65 97 76 13 27 490 - - - - - - - -MAXINT 49 38 65 97 76 13 27 491 0 - - - - - - -MAXINT 49 38 65 97 76 13 27 492 0 1 - - - - - -MAXINT 49 38 65 97 76 13 27 492 3 1 0 - -

12、 - - -MAXINT 49 38 65 97 76 13 27 492 3 1 4 0 - - - -MAXINT 49 38 65 97 76 13 27 492 3 1 5 0 4 - - -MAXINT 49 38 65 97 76 13 27 496 3 1 5 0 4 2 - -MAXINT 49 38 65 97 76 13 27 496 3 1 5 0 4 7 2 -MAXINT 49 38 65 97 76 13 27 496 8 1 5 0 4 7 2 3图10.1表插入排序得到一个有序的链表,查找则只能进行顺序查找,而不能进行随机查找,如折半查找。为此,还需要对记录进行

13、重排。重排记录方法:按链表顺序扫描各结点,将第i个结点中的数据元素调整到数组的第i个分量数据域。因为第i个结点可能是数组的第j个分量,数据元素调整仅需将两个数组分量中数据元素交换即可,但为了能对所有数据元素进行正常调整,指针域也需处理。【算法10.3】1. j=l-r0.next;i=1; /指向第一个记录位置,从第一个记录开始调整2. 若i=l-length时,调整结束;否则,a. 若i=j,j=l-rj.next;i+;转(2) /数据元素应在这分量中,不用调整,处理下一个结点b. 若ji,l-ri.eleml-rj.elem; /交换数据元素p=l-rj.next; / 保存下一个结点地

14、址l-rj.next=l-i.next;l-i.next=j; / 保持后续链表不被中断j=p;i+;转(2) / 指向下一个处理的结点c. 若ji,while(jrj.next;/j分量中原记录已移走,沿j的指针域找寻原记录的位置转到(a)【例10.3】对表插入排序结果进行重排示例MAXINT 49 38 65 97 76 13 27 496 8 1 5 0 4 7 2 3MAXINT 13 38 65 97 76 49 27 496 (6) 1 5 0 4 8 2 3MAXINT 13 27 65 97 76 49 38 496 (6) (7) 5 0 4 8 1 3MAXINT 13 27 38 97 76 49 65 496 (6) (7) (7) 0 4 8 5 3MAXINT 13 27 38 49 76 97 65 496 (6) (7) (7) (6) 4 0 5 3

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 其它相关文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号