《第十章内部排序.ppt》由会员分享,可在线阅读,更多相关《第十章内部排序.ppt(105页珍藏版)》请在三一办公上搜索。
1、1,第十章 内部排序,1、概述2、插入排序3、交换排序4、选择排序5、归并排序6、基数排序,2,排序的分类:内部排序:全部记录都可以同时调入内存进行的排序。外部排序:文件中的记录太多,无法全部将其同时调入内存进行的排序。,1、概述,3,定义:设有记录序列:R1、R2.Rn 其相应的关键字序列为:K1、K2.Kn;若存在一种确定的关系:Kx=Ky=Kz 则将记录序列 R1、R2.Rn 排成按该关键字有序的 序列 Rx、Ry.Rz 的操作,称之为排序。关系是任意的,如通常使用的小于、大于等关系。稳定与不稳定:若记录序列中的任意两个记录 Rx、Ry 的关键字 Kx=Ky;如果在排序之前和排序之后,它
2、们的相对位置保持不变,则这种排序方法是稳定的,否则是不稳定的。,4,define MAXSIZE 20typedef int KeyType;typedef struct KeyType key;InfoType otherinfo;RedType;,typedef struct RedType r MAXSIZE+1;/r0 空或作哨兵 int length;SqList;,5,r0 用作哨兵。共执行 5 遍操作。每遍操作:先将元素复制内容放入r0,再将本元素同已排序的序列,从尾开始进行比较。在已排序的序列中寻找自己的位置,进行插入。或者寻找不到,则一直进行到哨兵为止。意味着本元素最小,应该
3、放在 r1。每一遍,排序的序列将增加一个元素。如果序列中有 n 个元素,那么最多进行n 遍即可。,2、插入排序,例:36、24、10、6、12存放在 r 数组的下标为 1 至 5 的元素之中,用直接插入法将其排序。结果仍保存在下标为 1 至 5 的元素之中。,直接插入排序,6,0,1,2,36,24,10,6,12,3,4,5,36,24,24,7,0,1,2,36,24,10,6,12,3,4,5,36,24,8,0,1,2,36,24,10,6,12,3,4,5,36,24,24,9,0,1,2,36,24,10,6,12,3,4,5,36,10,24,10,10,0,1,2,36,24,
4、10,6,12,3,4,5,36,10,24,11,0,1,2,36,24,10,6,12,3,4,5,36,10,24,12,0,1,2,36,24,10,6,12,3,4,5,36,10,24,10,13,0,1,2,36,24,10,6,12,3,4,5,36,24,6,10,6,14,0,1,2,36,24,10,6,12,3,4,5,36,24,6,10,15,0,1,2,36,24,10,6,12,3,4,5,36,24,6,10,16,0,1,2,36,24,10,6,12,3,4,5,36,24,6,10,17,0,1,2,36,24,10,6,12,3,4,5,36,24,6
5、,10,6,18,0,1,2,36,24,10,6,3,4,5,36,24,12,10,6,12,12,19,0,1,2,36,24,10,6,3,4,5,36,24,12,10,6,12,20,0,1,2,36,24,10,6,3,4,5,36,24,12,10,6,12,21,22,直接插入排序过程:整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序。,算法描述:,23,void straisort(JD r,int n)int i,j;for(i=2;i=n;i+)r0=ri;j=i-1;while(r0.keyr
6、j.key)rj+1=rj;j-;rj+1=r0;,typedef struct int key;float info;JD;,24,例,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)27,i=1(),i=7(13 38 49 65 76 97)27,27,97,76,65,49,38,27,0 1 2 3 4 5 6 7,25
7、,算法评价时间复杂度若待排序记录按关键字从小到大排列(正序)关键字比较次数:,记录移动次数:,0 1 2 3 4 5 6 7,13 27 38 49 65 76 97,26,若待排序记录按关键字从大到小排列(逆序)关键字比较次数:,记录移动次数:,0 1 2 3 4 5 6 7,97 76 65 49 38 27 13,27,若待排序记录是随机的,取平均值关键字比较次数:,记录移动次数:,T(n)=O(n),空间复杂度:S(n)=O(1),28,折半插入排序排序过程:用折半查找方法确定插入位置的排序叫。,例,i=1(30)13 70 85 39 42 6 20,i=2 13(13 30)70
8、85 39 42 6 20,i=7 6(6 13 30 39 42 70 85)20,.,i=8 20(6 13 20 30 39 42 70 85),29,void binsort(JD r,int n)int i,j,x,s,m,k;for(i=2;i=n;i+)r0=ri;x=ri.key;s=1;j=i-1;while(s=j)m=(s+j)/2;if(xrm.key)j=m-1;else s=m+1;,for(k=i-1;k=s;k-)rk+1=rk;rs=r0;,30,算法描述:,算法评价时间复杂度:T(n)=O(n)空间复杂度:S(n)=O(1),31,希尔排序(缩小增量法)排序
9、过程:先取一个正整数d1n,把所有相隔d1的记录放一组,组内进行直接插入排序;然后取d2d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止。,32,33,#define T 3int d=5,3,1;/最后一个元素必为1void shellsort(JD r,int n,int dT)int i,j,k;JD x;/中间变量 for(k=0;kT;k+)/T等于几,进行几趟shell排序 for(i=dk+1;i=n;i+)x=ri;j=i-dk;/直接插入排序法j=i-1,34,while(j0)/直接插入排序法?,35,算法描述,#define T 3int d=5
10、,3,1;,49,13,38,27,27,4,55,38,65,48,97,55,76,4,1 2 3 4 5 6 7 8 9 10,1 2 3 4 5 6 7 8 9 10,1 2 3 4 5 6 7 8 9 10,最后一趟希尔排序与直接插入排序相同,36,希尔排序特点子序列的构成不是简单的“逐段分割”,而是将相隔某个增量的记录组成一个子序列希尔排序可提高排序速度,因为分组后n值减小,n更小,而T(n)=O(n),所以T(n)从总体上看是减小了关键字较小的记录跳跃式前移,在进行最后一趟增量为1的插入排序时,序列已基本有序增量序列取法没有除1以外的公因子最后一个增量值必须为1,37,3、交换排
11、序冒泡排序排序过程将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r1.keyr2.key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止,38,例,38,49,76,97,13,97,27,97,30,97,13,76,76,76,27,30,13,65,27,65,30,65,13,13,49,49,30,49,27,38,27,38
12、,30,38,1 2 3 4 5 6 7 8,39,void bubble_sort(JD r,int n)int m,i,j,flag=1;JD x;m=n-1;while(m0)j+),if(rj.keyrj+1.key)flag=1;x=rj;rj=rj+1;rj+1=x;m-;,40,算法描述:,算法评价时间复杂度最好情况(正序)比较次数:n-1移动次数:0最坏情况(逆序)比较次数:,移动次数:,空间复杂度:S(n)=O(1),T(n)=O(n),41,快速排序基本思想:通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记
13、录进行排序,以达到整个序列有序。,42,排序过程:对rst中记录进行一趟快速排序,附设两个指针i和j,设枢轴记录rp=rs,x=rp.key初始时令i=s,j=t首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换重复上述两步,直至i=j为止再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止,43,完成一趟排序:(27 38 13)49(76 97 65 50),分别进行快速排序:(13)27(38)49(50 65)76(97),快速排序结束:13 27 38 49 50 65 76 97,49,27,
14、49,65,13,49,49,97,44,void qksort(JD r,int t,int w)int i,j,k;JD x;if(t=w)return;i=t;j=w;x=ri;while(i=x.key)j-;if(ij)ri=rj;i+;while(ij),ri=x;qksort(r,t,j-1);qksort(r,j+1,w);,45,x.key=49,完成一趟排序:(27 38 13)49(76 97 65 50),27,65,13,49,97,算法描述:,46,算法评价时间复杂度最好情况(每次总是选到中间值作枢轴)T(n)=O(nlog2n)最坏情况(每次总是选到最小或最大元素
15、作枢轴)T(n)=O(n),空间复杂度:需栈空间以实现递归最坏情况:S(n)=O(n)一般情况:S(n)=O(log2n),T(n)=O(n),47,课外学习,看书 P263277题集 10.1(1)(2)(3)补充题:写出希尔排序的算法写出快速排序的算法,48,4、选择排序(Selection Sort)简单选择排序(Simple Selection Sort)排序过程首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换;再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换;重复上述操作,共进行n-1趟排序后,排序结束。,49,例
16、,初始:49 38 65 97 76 13 27,i=1,13,49,一趟:13 38 65 97 76 49 27,i=2,27,38,六趟:13 27 38 49 65 76 97,排序结束:13 27 38 49 65 76 97,50,void smp_selesort(JD r,int n)int i,j,k;JD x;for(i=1;in;i+)/n-1趟比较 k=i;for(j=i+1;j=n;j+)/每趟比较次数为n-i 次 if(rj.keyrk.key)k=j;,if(i!=k)/交换 x=ri;ri=rk;rk=x;,算法描述,51,算法评价时间复杂度记录移动次数最好情况
17、:0最坏情况:3(n-1)比较次数:,空间复杂度:S(n)=O(1),T(n)=O(n),52,堆排序堆的定义:n个元素的序列(k1,k2,kn),当且仅当满足下列关系时,称之为堆。,例(96,83,27,38,11,9),例(13,38,27,50,76,65,49,97),可将堆序列看成完全二叉树,则堆顶元素(完全二叉树的根)必为序列中n个元素的最小值或最大值。,53,满二叉树 在一棵二叉树中,如果所有分枝结点都有左子树和右子树,并且所有叶结点都在同一层上,这样的二叉树称作满二叉树。,54,完全二叉树 一棵深度为 k 的有 n 个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号
18、,如果编号为 i(1 i n)的结点与满二叉树中编号为 i 的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。,55,对于具有 n 个结点的完全二叉树,如果按照从上至下、从左到右的顺序对二叉树中的所有结点从 1 开始顺序编号,则对于任意的序号为 i 的结点,有:性质5如果 2i n,则序号为 i 的结点的左孩子结点的序号为 2i;如果 2i n,则序号为 i 的结点无左孩子如果 2i+1 n,则序号为 i 的结点的右孩子结点的序号为 2i+1;如果 2i+1 n,则序号为 i 的结点无右孩子完全二叉树的顺序存储,56,堆排序:将无序序列建成一个堆,得到关键字最小(或最大)的记录;输出堆顶
19、的最小(大)值后,使剩余的n-1个元素重又建成一个堆,则可得到n个元素的次小值;重复执行,得到一个有序序列,这个过程叫(Heap Sort)堆排序需解决的两个问题:如何由一个无序序列建成一个堆?如何在输出堆顶元素之后,调整剩余元素,使之成为一个新的堆?,57,第二个问题解决方法筛选方法:输出堆顶元素之后,以堆中最后一个元素替代之;然后将根结点值与左、右子树的根结点值进行比较,并与其中小者进行交换;重复上述操作,直至叶子结点,将得到新的堆,称这个从堆顶至叶子的调整过程为“筛选”。,58,例:,59,60,61,算法描述,int sift(JD r,int k,int m)/k,m为调整范围,除/
20、rk.key之外均满足堆的定义 int i,j;JD x;i=k;x=ri;j=2*i;,62,while(jrj+1.key)j+;/j为i的值小的孩子 if(x.keyrj.key)ri=rj;/rj上移 i=j;j*=2;else j=m+1;ri=x;,63,第一个问题解决方法方法:从无序序列的第n/2个元素(即此无序序列对应的完全二叉树的最后一个非终端结点)起,至第一个元素止,进行反复筛选。,64,例 含8个元素的无序序列(49,38,65,97,76,13,27,50),50,97,13,65,38,13,27,49,65,算法描述,void heapsort(JD r,int n
21、)int i;JD x;for(i=n/2;i=1;i-)sift(r,i,n);,for(i=n;i=2;i-)x=r1;r1=ri;ri=x;sift(r,1,i-1);,66,算法评价时间复杂度:最坏情况下T(n)=O(nlogn)空间复杂度:S(n)=O(1),67,课外学习,看书 P277284题集 10.1(4)(5)上机题:输入一关键字序列分别用希尔排序、快速排序、堆排序的算法进行排序。,68,5、归并排序(Merging Sort)归并将两个或两个以上的有序表组合成一个新的有序表,叫2-路归并排序排序过程设初始序列含有n个记录,则可看成n个有序的子序列,每个子序列长度为1两两合
22、并,得到n/2 个长度为2或1的有序子序列再两两合并,如此重复,直至得到一个长度为n的有序序列为止,69,将下属两个已排序的顺序表合并成一个有序表。顺序比较两者的相应元素,小者移入另一表中,反复如此,直至其中任一表都移入另一表为止。,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,i,j,k,70,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,i,j,k,7,71,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,72,0
23、1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,73,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,74,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,75,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,65,76,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,
24、C,7,13,49,65,77,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,65,76,78,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,65,76,79,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,65,76,80,80,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,65,76,80,81,0
25、1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,65,76,80,至此 B 表的元素都已移入 C 表,只需将 A 表的剩余部分移入 C 表即可。,82,0 1 2 3 4,49,13,65,97,76,7,80,A,B,0 1 2 3 4 5 6 7,C,7,13,49,65,76,80,至此 B 表的元素都已移入 C 表,只需将 A 表的剩余部分移入 C 表即可。,97,83,例,初始关键字:49 38 65 97 76 13 27,一趟归并后:38 49 65 97 13 76 27,二趟归并后:38 49 65 97 1
26、3 27 76,三趟归并后:13 27 38 49 65 76 97,84,void mergesort(JD r,int n)int i,s=1;JD tM;while(sn)tgb(s,n,r,t);/一趟归并,结果在t中 s*=2;if(sn)tgb(s,n,t,r);s*=2;/再次归并,结果在r中 else/奇数次归并,结果在t中,需要放回r中 i=1;while(i=n)ri=ti+;,85,void tgb(int s,int n,JD r,JD t)/一趟归并 int i=1;while(i=(n-2*s+1)/r中有两个完整的待归并序列,/即,ri.i+s-1、ri+s.i+
27、2*s-1 merge(r,i,i+s-1,i+2*s-1,t);i=i+2*s;if(i(n-s+1)/待归并序列为ri.i+s-1、ri+s.n merge(r,i,i+s-1,n,t);else/待归并序列只有一个,为ri.n,while(i=n)ti=ri+;,86,void merge(JD r,int h,int m,int w,JD t)/将一维数组中前后相邻的两个有序序列rh.m、rm+1.w归并为一个有序序列 int i,j,k;/i序列一下标,j序列二下标,k为t数组下标 i=h;j=m+1;k=h-1;while(i=m),87,if(im)/序列一已排完 while(j
28、=w)t+k=rj+;else/序列二已排完 while(i=m)t+k=ri+;/将剩余的序列一复制到t数组,88,算法评价时间复杂度:T(n)=O(nlog2n)空间复杂度:S(n)=O(n),89,6、基数排序(Radix Sorting)基数排序是借助多关键字排序思想什么是多关键字排序:,例:对52张扑克牌按以下次序排序:23A23A23A23A两个关键字:花色()面值(23A)并且“花色”地位高于“面值”,90,多关键字排序方法最高位优先法(MSD):先对最高位关键字k1(如花色)排序,将序列分成若干子序列,每个子序列有相同的k1值;然后让每个子序列对次关键字k2(如面值)排序,又分
29、成若干更小的子序列;依次重复,直至就每个子序列对最低位关键字kd排序;最后将所有子序列依次连接在一起成为一个有序序列。,91,最低位优先法(LSD):从最低位关键字kd起进行排序,然后再对高一位的关键字排序,依次重复,直至对最高位关键字k1排序后,便成为一个有序序列。MSD与LSD不同特点按MSD排序,必须将序列逐层分割成若干子序列,然后对各子序列分别排序。按LSD排序,不必分成子序列,对每个关键字都是整个序列参加排序;并且可不通过关键字比较,而通过若干次分配与收集实现排序。,92,链式基数排序基数排序:借助“分配”和“收集”对单逻辑关键字进行排序的一种方法链式基数排序:用静态链表作存储结构的
30、基数排序,typedef struct node int key;/关键字域 float info;/其他信息域 int link;/指针域,存放下一个数组元素的下标JD;,93,链式基数排序步骤设置10个队列,fi和ei分别为第i个队列的头指针和尾指针;第一趟分配对最低位关键字(个位)进行,改变记录的指针值,将链表中记录分配至10个链队列中,每个队列记录的关键字的个位相同;第一趟收集是改变所有非空队列的队尾记录的指针域,令其指向下一个非空队列的队头记录,重新将10个队列链成一个链表;重复上述两步,进行第二趟、第三趟分配和收集,分别对十位、百位进行,最后得到一个有序序列。,94,例,95,96
31、,97,#define D 3/结点结构typedef struct node int key;float info;int link;JD;,算法描述,98,int radixsort(JD r,int n)int i,j,k,t,p,rd,rg,f10,e10;for(i=1;in;i+)ri.link=i+1;/指向下一元素 rn.link=0;/最后一元素指针域为0,静态链结束 p=1;rd=1;rg=10;/p为静态链指针 for(i=1;i=D;i+)/D为关键字位数 for(j=0;j10;j+)fj=0;ej=0;/10个队列头、尾指针置初值,99,do/分配 k=(rp.ke
32、y%rg)/rd;/*首次rd=1,rg=10,即取关 键字的个位;以后rd,rg分别扩大10倍*/if(fk=0)/fk为空链 fk=p;else rek.link=p;/fk不空,p结点连在队尾 ek=p;/改写队尾指针 p=rp.link;/p指针指向下一个结点 while(p0);/静态链表中的元素链入10个队列,100,j=0;/收集 while(fj=0)j+;/找到第一个非空队列 p=fj;t=ej;/p为收集链链头,t为收集链链尾 for(k=j+1;k0)rt.link=fk;t=ek;rt.link=0;rg*=10;rd*=10;return(p);,101,算法评价时间
33、复杂度:分配:T(n)=O(n)收集:T(n)=O(rd)其中rd为基数T(n)=O(d(n+rd)其中:n记录数 d关键字位数 rd每位关键字取值范围 空间复杂度:S(n)=2rd个队列指针+n个指针域空间。,102,f0=0 e0=0f1=0 e1=0f2=0 e2=0f3=0 e3=0f4=0 e4=0f5=0 e5=0f6=0 e6=0f7=0 e7=0f8=0 e8=0f9=0 e9=0,1,1,2,2,3,3,4,4,5,6,6,7,7,8,9,10,103,f0=0 e0=0f1=0 e1=0f2=0 e2=0f3=0 e3=0f4=0 e4=0f5=0 e5=0f6=0 e6=0f7=0 e7=0f8=0 e8=0f9=0 e9=0,1,3,4,4,7,7,9,10,3,10,1,6,2,5,8,104,f0=0 e0=0f1=0 e1=0f2=0 e2=0f3=0 e3=0f4=0 e4=0f5=0 e5=0f6=0 e6=0f7=0 e7=0f8=0 e8=0f9=0 e9=0,4,4,7,9,2,8,7,9,2,8,3,1,10,6,5,105,课外学习,看书 P283289题集 10.1(6)10.3 10.4,
链接地址:https://www.31ppt.com/p-4723419.html