240 likes | 473 Vues
内部排序. 上海金融学院信息管理系. 第三章 内部排序. O 排序:按照结点中某字段的值的递增或递减次序重新排列线性表中各个结点的过程,称为排序。(本章按键值的递增次序排序) O 若任意两个键值相等的结点经过某方法排序后,仍保持原先的相对次序,则称这种排序方法是稳定的;否则是不稳定的。 O 排序时全部结点都存放在内存中,并在内存中调整等待排序的结点的存放位置,这类排序方法为内部排序。若排序前后的结点都存放在外存中,这类方法为外部排序。. 第三章 内部排序. 3.1 插入排序 3.2 选择排序 3.3 冒泡排序 3.4 希尔排序
E N D
内部排序 上海金融学院信息管理系
第三章 内部排序 O 排序:按照结点中某字段的值的递增或递减次序重新排列线性表中各个结点的过程,称为排序。(本章按键值的递增次序排序) O 若任意两个键值相等的结点经过某方法排序后,仍保持原先的相对次序,则称这种排序方法是稳定的;否则是不稳定的。 O 排序时全部结点都存放在内存中,并在内存中调整等待排序的结点的存放位置,这类排序方法为内部排序。若排序前后的结点都存放在外存中,这类方法为外部排序。
第三章 内部排序 3.1 插入排序 3.2 选择排序 3.3 冒泡排序 3.4 希尔排序 3.5 合并排序 3.6 快速排序 3.7 基数排序 例:将一副打乱的卜克牌由A23…JQK整理好,有几种方法?
3.1 插入排序 设线性表有n个结点a0, a1, …, an-1,可依次对ai (i=1, 2, …, n-1)执行插入操作: 设a0, a1, …, ai-1已排序,则有 a0≤ a1 ≤ … ≤ ai-1 现将ai送t,然后将t依次与ai-1,ai-2, …,比较,将比t大的结点依次向后移一个位置,直到某个aj ≤t,则将t送到aj+1;若直到a0均大于t,则将t送到a0的位置。 pp.72-73 插入算法
3.2 选择排序 插入排序算法:不断在已排好序的序列中为新结点找适合的位置。 选择排序算法:已排好序的序列不再照顾,只考虑将未排序的结点中最小的结点交换到最前面来。 若a0, a1, …, ai-1已排好序,考虑未排序的后面的结点ai, ai+1, …, an-1,从中选择最小的结点ak,然后将ak与ai交换。 p.74 选择排序算法
3.3 冒泡排序 对于结点序列a0, a1, …, an-1,起始的排序范围是a0至an-1。 在当前排序范围内,从头开始相邻两个结点依次比较,若有序,则不变;若失序,则交换。 若上一轮中最后交换的结点是aj,则本轮的排序范围是a0至aj。 pp. 75-76 冒泡排序算法
3.4 希尔排序 希尔排序考虑两个比较和交换的结点的距离要有一定的跨度,而不是象冒泡排序那样仅考虑相邻结点。 在执行希尔排序之前,首先给定一组严格递增的正整数(增量)d0, d1, …, dt-1,且dt-1=1 。 然后,对于i=0, 1, …, t-1,依次进行以下操作: 将当前序列中的结点按当前增量di分成di组,每组中结点的下标相差di,对所分的各组结点用插入排序方法进行排序。 p. 77 希尔排序的算法
作业:pp.86-87 3.1-3.4
3.5 合并排序 1.两个相邻的有序结点序列的合并算法; 2.对于n个结点的线性表,反复调用上述算法实现排序(合并排序)。
1.两个有序结点序列的合并算法 设线性表中相连的两部分 al, al+1, …, am 和 am+1, am+2, …, an 分别有序,现需将它们合并成一个有序结点序列,存放在另一线性表的相应位置 bl, bl+1, …, bm, bm+1, …, bn
1.两个有序结点序列的合并算法 (1)i=l,j=m+1,k=l (2)若i≤m,且j≤n,则 如果ai ≤aj,那么bk=ai,i++ ; 如果ai>aj,那么bk=aj,j++ ; 最后,k++,转(2). (3)若i≤m,则bk=ai,i++ ,k++,转(3). (4)若j≤n,则bk=aj,j++ ,k++,转(4). (5)算法结束. p. 78合并算法
2.合并排序 首先将n个结点的线性表看成n个长度为1的有序子序列,于是用前面的合并算法两两合并,得到n/2个长度为2的有序子序列; 然后对这些子序列用前面的合并算法两两合并,得到n/4个长度为4有序子序列; ……不断两两合并下去,最后得到长度为n的有序序列. pp.79-80 mpass() 一轮两两合并 p. 80 merge_sort() 合并排序
3.6 快速排序 思想: 基本算法为:在序列中取出某个结点,将它放在适当的位置并调整其他结点,使这结点左边结点的值均比其小,而这结点右边结点的值均比其大。 对适得其所的结点的左、右两边的序列,递归调用基本算法,以期所有结点找到合适的位置。
3.6 快速排序 设结点序列为a[low], a[low+1], …, a[up], 首先为a[low]找适合的位置,算法为: (1)i=low; j=up; t=a[low]; (2)如果 i≠j,则 ① 若a[j]>t,那么j--,转①; 否则,a[i]=a[j], i++,转②; ② 若a[i] ≤t,那么i++,转②; 否则,a[j]=a[i], j--,转(2)。 (3)如果 i=j,则a[i]=t,算法结束。
作业:p.87 3.5-3.6
3.7 基数排序 下面定义两个d元组(x0, x1, …, xd-1) 和(y0, y1, …, yd-1)的关系: (1)相等,当且仅当xi=yi(0≤i≤d-1)时。 (2)小于,当且仅当xi=yi(0≤i<j≤d-1),并xj<yj时。
3.7 基数排序 假设线性表的结点键值是由d元组 (k0, k1, …,kd-1) 组成。 基数排序有两种方法: (1)最高位优先(Most Significant Digit First,简记为MSD)排序 (2)最低位优先(Least Significant Digit First,简记为LSD)排序
(1)最高位优先(MSD)排序 首先按键值最高位k0排序,得到若干堆,每堆的k0值都相同; 再对每个堆按键值次高位k1进行排序,即将其再分成若干个子堆,每个子堆的k0和k1的值相同;……然后重复上述过程,直到按 kd-1的值再细分;最后把各堆放在一起。
(2)最低位优先(LSD)排序 首先按键值的最低位kd-1的值的大小把结点序列分成若干个子序列,再按kd-1的值从小到大依次把各个子序列收集为一个新的序列; 对新序列再根据次最低位kd-2值的大小分成若干个子序列,再按kd-2的值从小到大依次把各个子序列收集为一个新的序列; ……重复上述过程对kd-3, kd-4, …, k1, k0的值进行操作。最后的结点序列是已排序的序列。
3.7 基数排序 举例 整理扑克牌的过程有两种方法: 1.将牌分成黑桃、红心、方块、草花四堆,再在每堆中分A、2、3、…、10、J、Q、K,最后将堆按先后放在一起。(MSD) 2.将牌全部拿在一只手中,按 A、2、3、 …、10、J、Q、K 的次序,四张一组集中,继续拿在手中;然后从左到右依次抽出黑桃的13张牌,再红心、方块、草花,依次排在后面,还拿在手中。(LSD)
3.7 基数排序 考虑LSD排序算法 设结点序列a0, a1, …, an-1,结点键值为d元组 (k0, k1, …, kd-1) 其中,0≤kj≤r-1(0 ≤j ≤d-1,称kj以r为基)
3.7 基数排序 LSD排序过程中使用r个队列Q0, Q1, …, Qr-1,并依次对 i=d-1, d-2, …, 1, 0 各做一次“分配”和“收集”。 分配:开始时把Q0, Q1, …, Qr-1各个队列置空。然后,对于依次考察当前的线性表的结点,如果结点键值ki=k ,就把这个结点放进Qk的队列。 收集:把Q0, Q1, …, Qr-1各个队列的首尾相接,得到新的线性表。作为下次分配的当前线性表。
分配 集中 集中
第三章 内部排序 作业: pp. 86-87 3.7-----3.8