第9章内排序2

合集下载

数据结构-内排序

数据结构-内排序

Shell排序的性能分析
Shell排序的时间复杂度在O(nlog2n)和O(n2)间, Knuth的 统计结论是,平均比较次数和记录平均移动次数在n1.25与 1.6n1.25之间
Shell排序是一种不稳定的排序方法
最后谈一下delta的取法。 Shell最初的方案是delta=n/2, delta=delta/2,直到delta=1。Knuth的方案是delta=delta/3 +1。其它方案有:都取奇数为好;或delta互质为好等等。 而使用象1, 2, 4, 8, …或1, 3, 6, 9, …这样的增量序列就不太 合适,因为这样会使几个元素多次被分到一组中,从而造 成重复排序,产生大量无用的比较操作
另外,在无序子表中向前移动的过程中,如果没 有交换元素,则说明无序子表已有序,无须再做 排序
24
冒泡排序算法实现
1 void bubble_sort(RecType R[ ], int n) { 2 //待排序元素用一个数组R表示,数组有n个记录
3 int i, j; 4 bool swap=TRUE; //判断无序子表是否已有序的变量
内排序和外排序 按照排序过程中使用内、外存的不 同将排序方法分为内排序和外排序。若待排序记录全 部在内存中,称为内排序;若待排序记录的数量很大, 以致内存一次不能容纳全部记录,在排序过程中需要 进行内、外存交换,称为外排序。本章仅讨论内排序
内排序可分为五大类:插入排序、交换排序、选择排 序、归并排序和基数排序
直接插入排序(straight insert sort) 折半插入排序(binary insert sort) Shell排序(Shell sort)
10
10.2.1 直接插入排序举例

中国农业大学_821数据结构_《数据结构》习题(9)

中国农业大学_821数据结构_《数据结构》习题(9)

第9章内部排序一、问答题1. 什么是内部排序?什么是排序方法的稳定性?2. 对于本章介绍的内部排序方法,哪几种是稳定的?哪几种是不稳定的?对不稳定的排序方法试举例说明。

3. 对于给定的一组记录的关键字:23,13,17,21,30,60,58,28,30,90。

试分别写出用下列排序方法对其进行排序时,每一趟排序后的结果:(1)直接插入排序;(2)希尔排序;(3)冒泡排序;(4)直接选择排序;(5)快速排序(6)堆排序(7)归并排序。

4. 对长度为n的记录序列进行快速排序时,所需要的比较次数依赖于这n个元素的初始序列。

(1)n = 8时,在最好的情况下需要进行多少次比较?试说明理由。

(2)给出n = 8时的一个最好情况的初始排列实例。

5 试为下列各种情况选择合适的排序方法:(1)n = 30,要求在最坏的情况下,排序速度最快;(2)n = 30,要求排序速度既要快,又要排序稳定。

6. 判别以下序列是否为堆(所有的非叶子结点的关键字值k i均不大于其左右两个分支结点的关键字值k2和k2i+1。

),如果不是,则把它调整为堆。

(1)( 100, 86, 48, 73, 35, 39, 42, 57, 66, 21 );(2)( 12, 70, 33, 65, 24, 56, 48, 92, 86, 33 );(3)( 103, 97, 56, 38, 66, 23, 42, 12, 30, 52, 06, 20 );(4) ( 05, 56, 20, 03, 23, 40, 38, 29, 61, 05, 76, 28, 100 )。

7. 一组待排序记录的关键字是:986,321,123,432,500,654,018,765,987,210。

按照LSD方法写出基数排序的过程和结果。

8. 试证明:如果对于一个长度为n的任意文件进行排序,则至少需进行nlog2n次比较。

9. 试构造对5个整数元素进行排序,最多只用7次比较的算法思想。

数据结构第九章排序习题与答案

数据结构第九章排序习题与答案

习题九排序一、单项选择题1.下列内部排序算法中:A.快速排序 B.直接插入排序C. 二路归并排序D.简单选择排序E. 起泡排序F.堆排序(1)其比较次数与序列初态无关的算法是()(2)不稳定的排序算法是()(3)在初始序列已基本有序(除去n 个元素中的某 k 个元素后即呈有序, k<<n)的情况下,排序效率最高的算法是()(4)排序的平均时间复杂度为O(n?logn)的算法是()为 O(n?n) 的算法是()2.比较次数与排序的初始状态无关的排序方法是( )。

A.直接插入排序B.起泡排序C.快速排序D.简单选择排序3.对一组数据( 84, 47, 25, 15, 21)排序,数据的排列次序在排序的过程中的变化为(1) 84 47 25 15 21(2) 15 47 25 84 21(3) 15 21 25 84 47(4) 15 21 25 47 84则采用的排序是 ()。

A. 选择B.冒泡C.快速D.插入4.下列排序算法中 ( )排序在一趟结束后不一定能选出一个元素放在其最终位置上。

A. 选择B.冒泡C.归并D.堆5.一组记录的关键码为(46,79,56, 38,40, 84),则利用快速排序的方法,以第一个记录为基准得到的一次划分结果为()。

A. (38,40,46,56,79,84) B. (40,38,46,79,56,84)C. (40,38,46,56,79,84) D. (40,38,46,84,56,79)6.下列排序算法中,在待排序数据已有序时,花费时间反而最多的是()排序。

A.冒泡 B. 希尔C. 快速D. 堆7.就平均性能而言,目前最好的内排序方法是() 排序法。

A. 冒泡B.希尔插入C.交换D.快速8.下列排序算法中,占用辅助空间最多的是:()A. 归并排序B.快速排序C.希尔排序D.堆排序9.若用冒泡排序方法对序列 {10,14,26,29,41,52}从大到小排序,需进行()次比较。

数据结构教程 第九章 排序

数据结构教程 第九章 排序
2 插入排序


9.2.3 希尔排序
3.算法



void ShellSort() { gap=n/2;//初次增量取序列元素个数n的一半为步长 while(gap>0) { for(i=gap+1;i<=n;i++) { j=i-gap; while(j>0) { if(r[j]>r[j+gap]) { x=r[j];r[j]=r[j+gap];r[j+gap]=x; j=j-gap; }//对子序列作直接插入排序 else j=0; } } gap=gap/2;}//每次减半,直至步长为1 上一页 }
上一页
下一页
9.3 快速排序法


9.3.2 快速排序
3【例9-5】对数据序列:70, 75, 69, 32, 88, 18, 16, 58进行快速排序如图9-3所示。 4.算法


void QuickSort(int low, int high)//递归形式的快速排序 { int pivotpos; if(low<high) { pivotpos=Partition(low,high); QuickSort(low,pivotpos-1);//对低子表递归排序 QucikSort(pivotpos+1,high);//对高子表递归排序 } }
9.2 插入排序


9.2.2 二分插入排序
3.算法



void BinsSort() { for(i=2;i<=n;i++) { r[0]=r[i];low=1;high=i-1;//将r[i]暂存到r[0] while(low<=high) //在r[low..high]中折半查找有序插入的位置 { m=(low+high)/2;//折半 if(r[0].key<r[m].key) high=m-1;//插入点在低半区 else low=m+1;//插入点在高半区 } for(j=i-1;j>high+1;--j) r[j+1]=r[j];//记录后移 r[high+1]r[0];//插入 } 上一页 下一页

数据结构第9章 排序

数据结构第9章 排序

R[3] 10
R[4] 60
R[5] 25
R[6] 30
R[7] 18 18 18 18
18 36 20

10 10 36
60 60 60
25 25 25
30 30 30
【算法】直接插入排序 void D_InsertSort(datatype R[ ], int n) { /*对排序表R[1]..R[n]进行直接插入排序,n是记录的 个数*/ for(i=2; i<=n; i++) if (R[i].key<R[i-1].key) {R[0]=R[i]; /*将R[i]插入R[1].. R[i-1]中, R[0]为监测哨*/ for(j=i-1; R[0].key<R[j].key; j--) R[j+1]=R[j]; /*后移记录*/ R[j+1]=R[0]; /*插入到合适位置*/ } }
空间性能:除排序表以外的内存占用情况。 时间性能:比较关键码的次数,数据移动的次数。 它们往往是排序表规模(n)的函数
6. 记录和排序表的数据结构
一般采用顺序结构存储排序表。 记录和排序表的类型定义如下: #define MAXNUM … /* MAXNUM 为足够大的数 typedef struct { keytype key; …… } datatype; datatype R[MAXNUM]; /*关键码字段*/ /*其它信息*/ /*记录类型*/ /*定义排序表的存储
第一趟排序结果,使得间隔为5的字表有序: P=3
29 7 41 30 11 39 50 76 41 13 10 0 80 78 86
子序列分别为:{29,30,50,13,78},{7,11,76,100,86}, {41,39,41,80}。第二趟排序结果: P=1

数据结构第9章 排序

数据结构第9章 排序

数据结构第9章排序数据结构第9章排序第9章排名本章主要内容:1、插入类排序算法2、交换类排序算法3、选择类排序算法4、归并类排序算法5、基数类排序算法本章重点难点1、希尔排序2、快速排序3、堆排序4.合并排序9.1基本概念1.关键字可以标识数据元素的数据项。

如果一个数据项可以唯一地标识一个数据元素,那么它被称为主关键字;否则,它被称为次要关键字。

2.排序是把一组无序地数据元素按照关键字值递增(或递减)地重新排列。

如果排序依据的是主关键字,排序的结果将是唯一的。

3.排序算法的稳定性如果要排序的记录序列中多个数据元素的关键字值相同,且排序后这些数据元素的相对顺序保持不变,则称排序算法稳定,否则称为不稳定。

4.内部排序与外部排序根据在排序过程中待排序的所有数据元素是否全部被放置在内存中,可将排序方法分为内部排序和外部排序两大类。

内部排序是指在排序的整个过程中,待排序的所有数据元素全部被放置在内存中;外部排序是指由于待排序的数据元素个数太多,不能同时放置在内存,而需要将一部分数据元素放在内存中,另一部分放在外围设备上。

整个排序过程需要在内存和外存之间进行多次数据交换才能得到排序结果。

本章仅讨论常用的内部排序方法。

5.排序的基本方法内部排序主要有5种方法:插入、交换、选择、归并和基数。

6.排序算法的效率评估排序算法的效率主要有两点:第一,在一定数据量的情况下,算法执行所消耗的平均时间。

对于排序操作,时间主要用于关键字之间的比较和数据元素的移动。

因此,我们可以认为一个有效的排序算法应该是尽可能少的比较和数据元素移动;第二个是执行算法所需的辅助存储空间。

辅助存储空间是指在一定数据量的情况下,除了要排序的数据元素所占用的存储空间外,执行算法所需的存储空间。

理想的空间效率是,算法执行期间所需的辅助空间与要排序的数据量无关。

7.待排序记录序列的存储结构待排序记录序列可以用顺序存储结构和和链式存储结构表示。

在本章的讨论中(除基数排序外),我们将待排序的记录序列用顺序存储结构表示,即用一维数组实现。

北京师范大学数据结构教学资料第九章排序

北京师范大学数据结构教学资料第九章排序

第九章排序(基础知识)8.1 【答案】以关键字序列(265,301,751,129,937,863,742,694,076,438)为例,分别写出执行以下排序算法的各趟排序结束时,关键字序列的状态。

(1) 直接插入排序(2)希尔排序(3)冒泡排序(4)快速排序(5) 直接选择排序(6) 堆排序(7) 归并排序(8)基数排序上述方法中,哪些是稳定的排序?哪些是非稳定的排序?对不稳定的排序试举出一个不稳定的实例。

8.2 【答案】上题的排序方法中,哪些易于在链表(包括各种单、双、循环链表)上实现?8.3 【答案】当R[low..high]中的关键字均相同时,Partion返回值是什么?此时快速排序的的运行时间是多少?能否修改Partion,使得划分结果是平衡的(即划分后左右区间的长度大致相等)?8.4 【答案】若文件初态是反序的,则直接插入,直接选择和冒泡排序哪一个更好?8.5 【答案】若文件初态是反序的,且要求输入稳定,则在直接插入、直接选择、冒泡和快速排序中就选选哪种方法为宜?6. 用快速排序算法,对下列数组排序60 56 65 99 22 16 88 100a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]取a[0]为支点(pivot),列出第一轮升序排序后的元素顺序。

8.6 【答案】有序数组是堆吗?8.7 【答案】高度为h的堆中,最多有多少个元素?最少有多少个元素?在大根堆中,关键字最小的元素可能存放在堆的哪些地方?8.8 【答案】判别下列序列是否为堆(小根堆或大根堆),若不是,则将其调整为堆:(1) (100,86,73,35,39,42,57,66,21);(2) (12,70,33,65,24,56,48,92,86,33);(3) (103,97,56,38,66,23,42,12,30,52,06,20);(4) (05,56,20,23,40,38,29,61,35,76,28,100).8.9 【答案】将两个长度为n的有序表归并为一个长度为2n的有序表,最小需要比较n次,最多需要比较2n-1次,请说明这两种情况发生时,两个被归并的表有何特征?7. 将序列101 45 21 532 22 5 232 14 存放在一静态链表中(见下图),并对其按照链式基数排序法进行升序排序。

算法22-- 内部排序--基数排序

算法22-- 内部排序--基数排序
yes a<c<b
a<c no
c<a<b
c<b<a
• 注意:树高代表比较的代价。因此只要知道了树高和结点数 n 的关系,就可以求出 用比较法进行排序时的时间代价。另外,n 个结点的分类序列,其叶子结点 共有 n! 片。
17
9.7 内部排序方法的比较
比较次数 排序方法 最好 最差 最好 最差 移动次数
269
184 278 f[7] 083 f[8] f[9]
930
f[3] f[4] f[5]
063 f[6]
r[0]→ 505
008
109
930
063
269
278
083
184
589
2018/10/16
第二趟收集的结果:
r[0]0
063
269
278
083
184
589
第三趟分配(按最高位 i = 1 ) e[0] 083 063 008 f[0] 第三趟收集 184 109 f[1] 278 269 f[2] f[3] f[4] 589 505 f[5] f[6] f[7] f[8] 930 f[9] e[1] e[2] e[3] e[4] e[5] e[6] e[7] e[8] e[9]
2018/10/16



j = 0; // 开始从0号队列(总共radix个队)开始收集 while ( f [j] == 0 ) j++; // 若是空队列则跳过 r[0].next=p = f [j]; //建立本趟收集链表的头指针 int last = e[j]; //建立本趟收集链表的尾指针 for ( k = j+1; k < radix; k++) // 逐个队列链接(收集) if ( f [k] ) { //若队列非空 r[last].next=f [k]; last = e[k]; //队尾指针链接 } r[last].next=0; //本趟收集链表之尾部应为0 } } // RadixSort
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1
点编号必为n/2 !!(性质5)
4291
2
25
3
4291
i=3: 49大于08,不必调整; i=2: 25大于25*和16,也不必调整;
4
56
i=1: 21小于25和49,要调整!
25* 16 08
而且21还应当向下比较!! 17
9.4.2 堆排序 关键问题1:如何新建堆?
算法描述: for (i=n/2; i>=1; i--)
过程中关键码最小的记录位置。
21
25
49
28
16 08
index
index index
7
9.4.1 直接选择排序
需解决的关键问题?
⑵如何确定最小记录交换后的最终位置?
解决方法:
第i趟简单选择排序的待排序区间是r[i] ~ r[n],则r[i]
是无序区第一个记录,所以,将index所记载的关键 码最小的记录与r[i]交换。
4
9.4.1 直接选择排序
5、直接选择排序的过程
初始 21
0
i = 1 21
25
49
25*
16
08
12345
最小者 08
25
49 25*
16
交换21,08 08
最小者 16
i=20825源自49 25* 1621 交换25,16
最小者 21
i=3
08
16
49 25* 25
21 交换49,21
5
9.4.1 直接选择排序
1
主要内容
9.1 排序的基本概念 9.2 插入排序 9.3 交换排序 9.4 选择排序 9.5 归并排序 9.6 分配排序 9.7 性能比较
2
9.4 选择排序
选择排序的主要操作是选择,其主要思想是:每趟排序在当 前待排序序列中选出关键码最小的记录,添加到有序序列中。
有序序列
无序序列
r1 r2 …… r1 r2 ……
i=4
08 0
i=5
08
最小者 25*
16
21
25*
25
49 无交换
12345
最小者 25
16
21
25*
25
49 无交换
结果
08
16
21
25* 25
49
各趟排序后的结果
6
9.4.1 直接选择排序
需解决的关键问题?
⑴如何在无序区中记录关键码最小的记录?
解决方法: 设置一个整型变量index,用于记录在一趟比较的
8
9.4.1 直接选择排序 7、直接选择排序的算法
void SelectSort ( elemtype L[],int n )
{
for ( i = 1; i < n; i++ ) /*总共进行n-1次排序*/
{ k = i;
for ( j = i+1; j <n; j++)
/*在剩余记录序列中选择最小的记录*/
1 2345 1 2345 1 2345 1 2 345 1 2345
10
9.4.1 直接选择排序
移动次数: 最好情况(正序):0次
最坏情况:3(n-1)次
比较次数:
n-1
(n
i =1
-i)=
12n(n
-1)
=O(n2 )
45 231 15234 1 2 53 4 1 2 35 4 1 2 3 45
√ (大根堆) (大顶堆) (最大堆)
15
9.4.2 堆排序 2、堆排序的基本思想
将原始记录序列建成一个堆,称之为初始堆,并 输出堆顶元素;调整剩余的记录序列,使之成为一个新 堆,再输出堆顶元素;如此反复,当堆中只有一个元素 时,整个序列的排序结束,输出的序列就是原始序列的 有序排列。
主要要解决的关键问题: 1、如何将原始记录序列建成一个堆,即新建堆? 2、如何处理堆顶记录? 3、如何将剩余记录调整成一个新堆, 即重建堆?
ri-1 ri … rk … rn
交换 最小记录
ri-1 ri ri+1… ri … rn
常用的选择排序算法: (1)直接选择排序 (2)堆排序
3
9.4 选择排序
9.4.1 直接选择排序
1、基本思想 每经过一趟比较就找出一个最小值,与待排序列最前面的位
置互换. 2、优点:实现简单 3、缺点:每趟只能确定一个元素,表长为n时需要n-1趟 4、前提:顺序存储结构
{ if ( r[j] < r[k] )
k = j;
} ? /* k记录当前最小排序码的位置*/
if ( k != i ) {
Swap ( r[i], r[k] );
} ? /*与第 i 个位置的元素对换*/
}
9
9.4.1 直接选择排序 8、直接选择排序算法的性能分析
移动次数: 最好情况(正序):0次
树中所有结点的值均大于(或小于)其左右孩子,此树的根 结点(即堆顶)必最大(或最小)。
13
9.4.2 堆排序 堆和序列的关系
50
38
45
32
36 40 28
采用顺序存储
20 18 28
1 2 3 4 5 6 7 8 9 10
50 38 45 32 36 40 28 20 18 28
将堆用顺序存储结构来存储,则堆对应一组序列。
减少关键码间的比较次数
查找最小值的同时,找出较小值
12
9.4.2 堆排序
1. 什么是堆?
堆的定义:设有n个数据元素的序列 k1,k2,…,kn,当且 仅当满足下述关系之一时,称之为堆。
ki ≤ k2i 或者 ki ≤ k2i+1
ki ≥ k2i ki ≥ k2i+1
i=1, 2,… n/2
解释:如果让满足以上条件的元素序列 (k1,k2,…,kn)顺 次排成一棵完全二叉树,则此树的特点是:
简单选择排序的时间复杂度为O(n2)。
空间性能:需一个辅助空间。 稳定性:是一种不稳定的排序算法。
11
9.4 选择排序
9.4.2 堆排序--直接选择排序法的改进算法
改进的着眼点:如何减少关键码间的比较次数。若 能利用每趟比较后的结果,也就是在找出键值最小 记录的同时,也找出键值较小的记录,则可减少后 面的选择中所用的比较次数,从而提高整个排序过 程的效率。
14
9.4.2 堆排序 例:有序列T1=(08, 25, 49, 46, 58, 67)和序列T2=(91, 85, 76, 66, 58, 67, 55),判断它们是否 “堆”?
1
08
2
3
25
49
4
56
46 58 67
1
91
2
3
85
76
4
56 7
66 58 67 55
√ (小根堆) (小顶堆) (最小堆)
16
9.4.2 堆排序
为什么?
关键问题1:如何新建堆?
步骤:首先将一个待排序的记录序列按原始顺序建成一个完全 二叉树。从最后一个非终端结点开始往前逐步调整,使 每个双亲都大于(或小于)它的子女,直到根结点为止。
例:关键字序列T= (21,25,49,25*,16,08),请建大根堆。
完全二叉树的最后一个非终端结
相关文档
最新文档