《数据结构》内部排序 (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次比较的算法思想。

数据结构教程 第九章 排序

数据结构教程 第九章 排序
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];//插入 } 上一页 下一页

《数据结构》期中题库及答案

《数据结构》期中题库及答案

一、判断题:1、线性表的逻辑顺序与物理顺序总是一致的。

( )2、线性表的顺序存储表示优于链式存储表示。

( )3、线性表若采用链式存储表示时所有结点之间的存储单元地址可连续可不连续。

( )4、二维数组是其数组元素为线性表的线性表。

( )5、每种数据结构都应具备三种基本运算:插入、删除和搜索。

( )6、数据结构概念包括数据之间的逻辑结构,数据在计算机中的存储方式和数据的运算三个方面。

( )7、线性表中的每个结点最多只有一个前驱和一个后继。

()8、线性的数据结构可以顺序存储,也可以链接存储。

非线性的数据结构只能链接存储。

()9、栈和队列逻辑上都是线性表。

()10、单链表从任何一个结点出发,都能访问到所有结点()11、删除二叉排序树中一个结点,再重新插入上去,一定能得到原来的二叉排序树。

()12、快速排序是排序算法中最快的一种。

()13、多维数组是向量的推广。

()14、一般树和二叉树的结点数目都可以为0。

()15、直接选择排序是一种不稳定的排序方法。

()16、98、对一个堆按层次遍历,不一定能得到一个有序序列。

()17、在只有度为0和度为k的结点的k叉树中,设度为0的结点有n0个,度为k的结点有nk个,则有n0=nk+1。

()18、折半搜索只适用与有序表,包括有序的顺序表和有序的链表。

()19、堆栈在数据中的存储原则是先进先出。

()20、队列在数据中的存储原则是后进先出。

()21、用相邻矩阵表示图所用的存储空间大小与图的边数成正比。

()22、哈夫曼树一定是满二叉树。

()23、程序是用计算机语言表述的算法。

()24、线性表的顺序存储结构是通过数据元素的存储地址直接反映数据元素的逻辑关系。

()25、用一组地址连续的存储单元存放的元素一定构成线性表。

()26、堆栈、队列和数组的逻辑结构都是线性表结构。

()27、给定一组权值,可以唯一构造出一棵哈夫曼树。

()28、只有在初始数据为逆序时,冒泡排序所执行的比较次数最多。

数据结构课程设计—内部排序算法比较

数据结构课程设计—内部排序算法比较

数据结构课程设计—内部排序算法比较在计算机科学领域中,数据的排序是一项非常基础且重要的操作。

内部排序算法作为其中的关键部分,对于提高程序的运行效率和数据处理能力起着至关重要的作用。

本次课程设计将对几种常见的内部排序算法进行比较和分析,包括冒泡排序、插入排序、选择排序、快速排序和归并排序。

冒泡排序是一种简单直观的排序算法。

它通过重复地走访要排序的数列,一次比较两个数据元素,如果顺序不对则进行交换,并一直重复这样的走访操作,直到没有要交换的数据元素为止。

这种算法的优点是易于理解和实现,但其效率较低,在处理大规模数据时性能不佳。

因为它在最坏情况下的时间复杂度为 O(n²),平均时间复杂度也为O(n²)。

插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,直到整个序列有序。

插入排序在数据量较小时表现较好,其平均时间复杂度和最坏情况时间复杂度也都是 O(n²),但在某些情况下,它的性能可能会优于冒泡排序。

选择排序则是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。

以此类推,直到全部待排序的数据元素排完。

选择排序的时间复杂度同样为O(n²),但它在某些情况下的交换操作次数可能会少于冒泡排序和插入排序。

快速排序是一种分治的排序算法。

它首先选择一个基准元素,将数列分成两部分,一部分的元素都比基准小,另一部分的元素都比基准大,然后对这两部分分别进行快速排序。

快速排序在平均情况下的时间复杂度为 O(nlogn),最坏情况下的时间复杂度为 O(n²)。

然而,在实际应用中,快速排序通常表现出色,是一种非常高效的排序算法。

归并排序也是一种分治算法,它将待排序序列分成若干个子序列,每个子序列有序,然后将子序列合并成一个有序序列。

《数据结构排序》课件

《数据结构排序》课件

根据实际需求选择时间复杂度和空间 复杂度最优的排序算法,例如快速排 序在平均情况下具有较好的性能,但 最坏情况下其时间复杂度为O(n^2)。
排序算法的适用场景问题
适用场景考虑因素
选择排序算法时需要考虑实际应 用场景的特点,如数据量大小、 数据类型、是否需要稳定排序等 因素。
不同场景适用不同
算法
例如,对于小规模数据,插入排 序可能更合适;对于大规模数据 ,快速排序或归并排序可能更优 。
排序的算法复杂度
时间复杂度
衡量排序算法执行时间随数据量增长而增长的速率。时间复杂度越低,算法效 率越高。常见的时间复杂度有O(n^2)、O(nlogn)、O(n)等。
空间复杂度
衡量排序算法所需额外空间的大小。空间复杂度越低,算法所需额外空间越少 。常见的空间复杂度有O(1)、O(logn)、O(n)等。
在数据库查询中,经常需要对结果进行排序,以便用户能够快速找到所需信息。排序算 法的效率直接影响到查询的响应时间。
索引与排序
数据库索引能够提高查询效率,但同时也需要考虑到排序的需求。合理地设计索引结构 ,可以加速排序操作。
搜索引擎中的排序
相关性排序
搜索引擎的核心功能是根据用户输入的 关键词,返回最相关的网页。排序算法 需要综合考虑网页内容、关键词密度、 链接关系等因素。
VS
广告与排序
搜索引擎中的广告通常会根据关键词的竞 价和相关性进行排序,以达到最佳的广告 效果。
程序中的排序应用
数组排序
在程序中处理数组时,经常需要对其进行排 序。不同的排序算法适用于不同类型的数据 和场景,如快速排序、归并排序等。
数据可视化中的排序
在数据可视化中,需要对数据进行排序以生 成图表。例如,柱状图、饼图等都需要对数 据进行排序处理。

数据结构(c言版)课件_第八章_排序_(严蔚敏、吴伟民编_清华大学出版社)

数据结构(c言版)课件_第八章_排序_(严蔚敏、吴伟民编_清华大学出版社)

算法描述
算法评价
时间复杂度
记录移动次数
最好情况:0
最坏情况:3(n-1)
比较次数: n1 (n i) 1 (n2 n)
i 1
2
T(n)=O(n²)
空间复杂度:S(n)=O(1)
Ch8_6.c
堆排序
堆的定义:n个元素的序列(k1,k2,……kn),当且仅当 满足下列关系时,称之为堆
增量序列取法 无除1以外的公因子 最后一个增量值必须为1
8.2 交换排序
冒泡排序
排序过程
将第一个记录的关键字与第二个记录的关键字进行比较,若 为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第 三个记录;依次类推,直至第n-1个记录和第n个记录比较为 止——第一趟冒泡排序,结果关键字最大的记录被安置在最 后一个记录上
二趟排序:13 4 48 38 27 49 55 65 97 76
Ch8_3.c
希尔排序特点
子序列的构成不是简单的“逐段分割”,而是将相隔某个增 量的记录组成一个子序列
希尔排序可提高排序速度,因为 分组后n值减小,n²更小,而T(n)=O(n²),所以T(n)从总体 上看是减小了
关键字较小的记录跳跃式前移,在进行最后一趟增量为1 的插入排序时,序列已基本有序
9776
7163
6257 13
4390 27
3308
38
9173 76
7267 13
6350 27
49 30
49
927 13
7360 27
65 30
65
9370 76
2977 30 76
3初0 9第7 第 第 第 第 第 始一二三四五六 关趟趟趟趟趟趟 键 字

《数据结构》实验报告——排序

《数据结构》实验报告——排序

《数据结构》实验报告排序实验题目:输入十个数,从插入排序,快速排序,选择排序三类算法中各选一种编程实现。

实验所使用的数据结构内容及编程思路:1.插入排序:直接插入排序的基本操作是,将一个记录到已排好序的有序表中,从而得到一个新的,记录增一得有序表。

一般情况下,第i趟直接插入排序的操作为:在含有i-1个记录的有序子序列r[1..i-1]中插入一个记录r[i]后,变成含有i个记录的有序子序列r[1..i];并且,和顺序查找类似,为了在查找插入位置的过程中避免数组下标出界,在r[0]处设置哨兵。

在自i-1起往前搜索的过程中,可以同时后移记录。

整个排序过程为进行n-1趟插入,即:先将序列中的第一个记录看成是一个有序的子序列,然后从第2个记录起逐个进行插入,直至整个序列变成按关键字非递减有序序列为止。

2.快速排序:基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

假设待排序的序列为{L.r[s],L.r[s+1],…L.r[t]},首先任意选取一个记录(通常可选第一个记录L.r[s])作为枢轴(或支点)(pivot),然后按下述原则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较大的记录都安置在它的位置之后。

由此可以该“枢轴”记录最后所罗的位置i作为界线,将序列{L.r[s],…,L.r[t]}分割成两个子序列{L.r[i+1],L.[i+2],…,L.r[t]}。

这个过程称为一趟快速排序,或一次划分。

一趟快速排序的具体做法是:附设两个指针low和high,他们的初值分别为low和high,设枢轴记录的关键字为pivotkey,则首先从high所指位置起向前搜索找到第一个关键字小于pivotkey的记录和枢轴记录互相交换,然后从low所指位置起向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录互相交换,重复这两不直至low=high为止。

数据结构(C语言版)实验报告 (内部排序算法比较)

数据结构(C语言版)实验报告 (内部排序算法比较)

《数据结构与算法》实验报告一、需求分析问题描述:在教科书中,各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。

试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。

基本要求:(l)对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

(2)待排序表的表长不小于100000;其中的数据要用伪随机数程序产生;至少要用5组不同的输入数据作比较;比较的指标为有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动)。

(3)最后要对结果作简单分析,包括对各组数据得出结果波动大小的解释。

数据测试:二.概要设计1.程序所需的抽象数据类型的定义:typedef int BOOL; //说明BOOL是int的别名typedef struct StudentData { int num; //存放关键字}Data; typedef struct LinkList { int Length; //数组长度Data Record[MAXSIZE]; //用数组存放所有的随机数} LinkList int RandArray[MAXSIZE]; //定义长度为MAXSIZE的随机数组void RandomNum() //随机生成函数void InitLinkList(LinkList* L) //初始化链表BOOL LT(int i, int j,int* CmpNum) //比较i和j 的大小void Display(LinkList* L) //显示输出函数void ShellSort(LinkList* L, int dlta[], int t,int* CmpNum, int* ChgNum) //希尔排序void QuickSort (LinkList* L, int* CmpNum, int* ChgNum) //快速排序void HeapSort (LinkList* L, int* CmpNum, int* ChgNum) //堆排序void BubbleSort(LinkList* L, int* CmpNum, int* ChgNum) //冒泡排序void SelSort(LinkList* L, int* CmpNum, int* ChgNum) //选择排序void Compare(LinkList* L,int* CmpNum, int* ChgNum) //比较所有排序2 .各程序模块之间的层次(调用)关系:二、详细设计typedef int BOOL; //定义标识符关键字BOOL别名为int typedef struct StudentData //记录数据类型{int num; //定义关键字类型}Data; //排序的记录数据类型定义typedef struct LinkList //记录线性表{int Length; //定义表长Data Record[MAXSIZE]; //表长记录最大值}LinkList; //排序的记录线性表类型定义int RandArray[MAXSIZE]; //定义随机数组类型及最大值/******************随机生成函数********************/void RandomNum(){int i; srand((int)time(NULL)); //用伪随机数程序产生伪随机数for(i=0; i小于MAXSIZE; i++) RandArray[i]<=(int)rand(); 返回;}/*****************初始化链表**********************/void InitLinkList(LinkList* L) //初始化链表{int i;memset(L,0,sizeof(LinkList));RandomNum();for(i=0; i小于<MAXSIZE; i++)L->Record[i].num<=RandArray[i]; L->Length<=i;}BOOL LT(int i, int j,int* CmpNum){(*CmpNum)++; 若i<j) 则返回TRUE; 否则返回FALSE;}void Display(LinkList* L){FILE* f; //定义一个文件指针f int i;若打开文件的指令不为空则//通过文件指针f打开文件为条件判断{ //是否应该打开文件输出“can't open file”;exit(0); }for (i=0; i小于L->Length; i++)fprintf(f,"%d\n",L->Record[i].num);通过文件指针f关闭文件;三、调试分析1.调试过程中遇到的问题及经验体会:在本次程序的编写和调试过程中,我曾多次修改代码,并根据调试显示的界面一次次调整代码。

大学《数据结构教程》(第5版) 李春葆 清华大学出版社课件第1章 绪论

大学《数据结构教程》(第5版)   李春葆     清华大学出版社课件第1章 绪论
D={ a,b,c,d,e,f,g}; R={<e,d>,<d,c>,<c,a>,<a,b>,<b,f> ,<f,g>}
edcabfg
存储结构
1)顺序存储结构 2)链式存储结构
地址 内容
地址 内容
0400 5.0
2字节 0400 5.0
2字节
0402 - 5.3
0402 0515
0515 - 5.3
例如,若T(n)=n(n+1)/2,则有 T(n)/n2=1/2+1/n, 当n∞时,T(n)/n2=1/2故它的时间复杂度为O (n2), 即T(n)与n2 数量级相同。
显然,被称做问题的基本操作的原操作应是其 重复执行次数与算法的执行时间成正比的原 操作;
多数情况下,它就是最深层循环内的语句中 的原操作,它的执行次数和包含它的语句频 度相同。
同样的数据对象,用不同的数据结构来表示, 运算效率可能有明显的差异。
程序设计的实质是对实际问题选择一个好的数 据结构,加之设计一个好的算法。而好的算法 在很大程度上取决于描述实际问题的数据结构。
1.1.2 基本概念和术语(学籍信息表)
• 数据(Data):是信息的载体,能够被计算机识别、 存储和加工处理。
++x;s+=x; } 时间复杂度为O(n)。
一重循环,其基本运算次数与问题规模 n成线性增长关系,称为线性阶,记为 O(n)
【例1-9】
for(j =1;j<=n;++j) for(k=1;k<=n;++k) {++x; s+=x;}
时间复杂度为O(n2)。 二重循环,其基本运算次数于问题规模n 成平方级增长关系,称为平方阶,记为 O(n2)。

李春葆《数据结构教程》(第4版)笔记和课后习题详解(内排序)【圣才出品】

李春葆《数据结构教程》(第4版)笔记和课后习题详解(内排序)【圣才出品】

第10章内排序10.1 复习笔记一、排序的基本概念1.定义排序,就是整理表中的元素,使之按关键字递增或递减的顺序排列,本章仅讨论递增排序的情况。

其确切定义如下:输入:n个元素,R0,R1,…,R n-1,相应的关键字分别为k0,k1,…,k n-1。

输出:R i0,R i1,…,R in-1,使得k i0≤k i1≤…≤k in-1。

因此,排序算法就是要确定0,1,…,n-1的一种排列i0,i1,…,i n-1,使表中的元素依此排列整理后按关键字有序。

2.排序的稳定性(1)稳定如果待排序的表中,存在多个关键字相同的元素,经过排序后这些具有相同关键字的元素之间的相对次序保持不变,则称这种排序方法是稳定的。

(2)不稳定若具有相同关键字的元素之间的相对次序发生变化,则称这种排序方法是不稳定的。

注意:排序算法的稳定性是针对所有输入实例而言的。

在所有可能的输入实例中,只要有一个实例使得算法不满足稳定性要求,则该排序算法就是不稳定的。

3.内排序和外排序(1)内排序在排序过程中,若整个表都是放在内存中处理,排序时不涉及内、外存数据的交换,则称之为内排序。

内排序适用于元素个数不很多的小表。

(2)外排序若排序过程中要进行内、外存数据的交换,则称之为外排序。

外排序则适用于元素个数很多,不能一次将全部元素放入内存的大表。

内排序是外排序的基础。

(3)排序方法的其他分类①需要关键字比较的排序需要关键字比较的排序方法有插入排序、选择排序、交换排序和归并排序等。

②不需关键字比较的排序不需要关键字比较的排序方法有基数排序。

4.排序数据的组织在本章中,以顺序表作为排序数据的存储结构,假设关键字类型为整型。

待排序的顺序表中数据元素的类型定义如下:二、插入排序1.插入排序的思想及方法基本思想是:每次将一个待排序的元素,按其关键字大小插入到已经排好序的子表中的适当位置,直到全部元素插入完成为止。

主要有两种插入排序方法,即直接插入排序和希尔排序。

数据结构chapter_10

数据结构chapter_10

typedef struct { //定义每个记录 数据元素) 定义每个记录( //定义每个记录(数据元素)的结构 KeyType key ; //关键字 //关键字 InfoType otherinfo; //其它数据项 //其它数据项 }RedType; //记录类型 //记录类型 typedef struct { //定义顺序表 定义顺序表L //定义顺序表L的结构 RecordType r [ MAXSIZE +1 ]; //存储顺序表的向量 //存储顺序表的向量 //r[0] r[0]一般作哨兵或缓冲区 //r[0]一般作哨兵或缓冲区 int length ; //顺序表的长度 //顺序表的长度 }SqList; //顺序表类型 //顺序表类型
void BInsertSort (SqList &L) {
// 对顺序表 作折半插入排序 对顺序表L作折半插入排序 for ( i=2; i<=L.length; ++i ) { L.r[0] = L.r[i]; // 将L.r[i]暂存到 暂存到L.r[0] 暂存到 low = 1; high = i-1; while (low<=high) { // 在r[low..high]中折半查找有序插入的位置 中折半查找有序插入的位置 m = (low+high)/2; // 折半 if (L.r[0].key < L.r[m].key) high = m-1; // 插入点在低半区 else low = m+1; // 插入点在高半区 } // while for ( j=i-1; j>=low; --j ) L.r[j+1] = L.r[j]; // 记录后移 // 插入 L.r[high+1] = L.r[0]; } } // BInsertSort

数据结构第十、十一章:排序

数据结构第十、十一章:排序

14
9.2 交换排序
冒泡排序
排序过程
将第一个记录的关键字与第二个记录的关键字进行比较, 将第一个记录的关键字与第二个记录的关键字进行比较,若 为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与 为逆序 ,则交换; 第三个记录;依次类推,直至第n-1个记录和第 个记录比较 个记录和第n个记录比较 第三个记录;依次类推,直至第 个记录和第 为止——第一趟冒泡排序,结果关键字最大的记录被安置在 第一趟冒泡排序, 为止 第一趟冒泡排序 最后一个记录上 对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的 个记录进行第二趟冒泡排序, 对前 个记录进行第二趟冒泡排序 记录被安置在第n-1个记录位置 记录被安置在第 个记录位置 重复上述过程,直到“ 重复上述过程,直到“在一趟排序过程中没有进行过交换记 录的操作” 录的操作”为止
按待排序记录所在位置
内部排序: 内部排序:待排序记录存放在内存 外部排序: 外部排序:排序过程中需对外存进行访问的排序
稳定排序和不稳定排序 假设Ki=Kj(1≤i≤n,1≤j≤n,i≠j),且在排序前的序列中Ri领先 假设 ( , , ),且在排序前的序列中 领先 ),且在排序前的序列中 于Rj(即i<j)。若在排序后的排序中Ri仍领先于 ,即那些具 ( )。若在排序后的排序中 仍领先于Rj, )。若在排序后的排序中 仍领先于 有相同关键字的记录,经过排序后它们的相对次序仍然保持不变, 有相同关键字的记录,经过排序后它们的相对次序仍然保持不变, 则称这种排序方法是稳定的;反之,若Rj领先于 ,则称所用的 则称这种排序方法是稳定的;反之, 领先于Ri, 领先于 方法是不稳定的。 方法是不稳定的。 按排序依据原则
4
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程的内容
1
第10章 内部排序
10.1 概述 10.2 插入排序 10.3 交换排序 10.4 选择排序 10.5 归并排序 10.6 基数排序
2
10.1 概述
1. 什么是排序? 将一组杂乱无章的数据按一定的规律顺次排列 排序的目的是什么? ——便于查找!
8
例2:关键字序列T= (21,25,49,25*,16,08),
请写出直接插入排序的具体实现过程。 *表示后一个25
解:假设该序列已存入一维数组V[7]中,将V[0]作为缓冲或 暂存单元,称为哨兵(Guard)。则程序执行过程为:
初态:
22410暂存55698*
021816
21516
2425591*
KeyType key ;
//关键字
InfoType otherinfo; //其它数据项
}RecordType ;
typedef struct {
//定义顺序表的结构
RecordType r [ MAXSIZE +1 ]; //存储顺序表的向量
//r[0]一般作哨兵或缓冲区
int length ; //顺序表的长度
7
1) 直接插入排序
最简单的排序法!
新元素插入到哪里? 在已形成的有序表中线性查找哨兵的 插入位置,把原来位置上的元素向后顺移。
例1:关键字序列L.r[0..8]=(哨兵,13,6,3,31,9,27,
5,11),请写出直接插入排序的中间过程序列。
【13】, 6, 3, 31, 9, 27, 5, 11
}SqList ;
5
7. 内部排序的算法有哪些?
——按排序的规则不同,可分为5类: • 插入排序 • 交换排序(重点是快速排序) • 选择排序 • 归并排序 • 基数排序
——按排序算法的时间复杂度不同,可分为3类: •简单的排序算法:时间效率低,O(n2) •先进的排序算法: 时间效率高,O( nlog2n ) •基数排序算算法:时间效率高,O( d×n)
对应程序参见教材P265。
9
直接插入排序的算法分析 若设待排序的记录个数为n,则算法需要进行
n-1次插入。 最好情况下,排序前记录已经按关键码大小从
小到大有序(正序):每趟只需与待插入记录 的直接前驱(它之前最后一个记录)的关键字 比较 1 次,不需移动。因此,总的关键字比 较次数为n-1。
10
//按增量序列dlta[0…t-1]对顺序表L作Shell排序
for(k=0;k<t;++k)
dk值依次装在dlta[t]中
ShellSort(L,dlta[k]); //增量为dlta[k]的一趟插入排序
} // ShellSort
20
希尔排序算法(其中某一趟的排序操作)
void ShellInsert(SqList &L,int dk) {
参见教材P272
//对顺序表L进行一趟增量为dk的Shell排序,dk为步长因子 for(i=dk+1;i<=L.length; ++ i) //开始将r[i] 插入有序增量子表
if(r[i].key < r[i-dk].key) {
r[0]=r[i];
//暂存在r[0]
for(j=i-dk; j>0 &&(r[0].key<r[j].key); j=j-dk) r[j+dk]=r[j]; //关键字较大的记录在子表中后移
pre = current;
// current指针准备后移, pre跟上;
current = SL.r[current].next; } //找插入位置
//(类似p=p->link)
SL.r[i].next = current; //新记录r[i]找到合适序位开始插入
SL.r[pre].next = i; //在pre与current之间链入
14
例:关键字序列 T=(21,25,49,25*,16,08),
请写出表插入排序的具体实现过程。
*表示后一个25
解:假设该序列(结构类型)已存入一维数组V[7]中,将V[0] 作为表头结点。则算法执行过程为:
初态 i=1
i=2 i=3 i=4 i=5 i=6
i 关键字 V[i].key
0
MAXINT
19
时间效率: O(n1.25)~O(1.6n1.25)——经验公式 空间效率:O(1)——因为仅占用1个缓冲单元 算法的稳定性:不稳定——因为49*排序后却到了49的前面
希尔排序算法(主程序)
参见教材P272
void ShellSort(SqList &L,int dlta[ ],int t){
12
折半插入排序的算法分析 • 折半查找比顺序查找快,所以折半插入排序
就平均性能来说比直接插入排序要快。 • 在插入第 i 个对象时,需要经过 log2i +1 次
关键码比较,才能确定它应插入的位置。因 此,将 n 个对象用折半插入排序所进行的关 键码比较次数为:n*log2n • 折半插入排序是一个稳定的排序方法。
SL.r[1].next = 0;
//形成循环链表
for ( int i = 2; i <= SL.length; i++ ) {
int current = SL.r[0].next; //current=当前记录指针
int pre = 0;
//pre=当前记录current的前驱指针
while ( SL.r[current].key <= SL.r[i].key) {
2459*
214569*
49 08
0 123456
完成!
i=1 i=2 i=3 i=4 i=5 i=6
时间效率: O(n2)——因为在最坏情况下,所有元素的比较
次数总和为(0+1+…+n-1)→O(n2)。其他情况
下还要加上移动元素的次数。
空间效率:O(1)——因为仅占用1个缓冲单元
算法的稳定性:稳定——因为25*排序后仍然在25的后面。
13
3)表插入排序
基本思想:在顺序存储结构中,给每个记录增开一个指针分 量,在排序过程中将指针内容逐个修改为已经整理(排序) 过的后继记录地址。 优点:在排序过程中不移动元素,只修改指针。
此方法具有链表排序和地址排序的特点。 回忆: ② 链表排序——排序时只移动指针; ③ 地址排序——排序时先移动地址,最后再移动记录。
j=[0..1]) j=[2..3])
【3, 【3,
6, 5,
9, 6,
193, 1, 23,7, 3217】, 31, 5】, 1, 111ii==67;;LL..rr[[00]]==257;移;移动动22++40次次(j(=j=[1[4..5])])
【3, 5, 6, 9, 11, 13, 27, 31】i=8;L.r[0]=11;移动2+4次(j=[1..5])
【6, 13】, 3, 31, 9, 27, 5, 11i=2;L.r[0]=6;移动2+0次(j=[0])
【3, 【3, 【3,
6, 6, 6,
13】, 31, 9, 13, 31】, 9, 9, 13, 31】,
27, 27, 27,
5, 5, 5,
11ii==34;;LL..rr[[00]]==33;1移; 动2+1次( 11i=5;L.r[0]=9;移动2+1次( 11
3.排序算法的好坏如何衡量?
• 时间效率——排序速度(即排序所花费的全部比较次数) • 空间效率——占内存辅助空间的大小 • 稳定性——若两个记录A和B的关键字值相等,但排序后A、
B的先后次序保持不变,则称这种排序算法是稳定的。
3
4. 什么叫内部排序?什么叫外部排序?
——若待排序记录都在内存中,称为内部排序; ——若待排序记录一部分在内存,一部分在外存,则
第2趟 (dk=3)
13 2074 49* 5358 0247 49 3585 65 97 76
第3趟 (dk=1)
1034 0143 4297* 38 4297* 49 55 65 9776 7967
算法分析:开始时dk 的值较大,子序列中的对象较少,排序速度 较快;随着排序进展,dk 值逐渐变小,子序列中对象个数 逐渐变多,由于前面工作的基础,大多数对象已基本有序, 所以排序速度仍然很快。
改进:可以根据表中指针线索,很快对所有记录重排, 形成真正的有序表(顺序存储方式),从而能满足 折半查找方式。具体实现见教材P269。
17
4)希尔(shell)排序(又称缩小增量排序)
基本思想:先将整个待排记录序列分割成若干子序列,分 别进行直接插入排序,待整个序列中的记录“基本有序” 时,再对全体记录进行一次直接插入排序。 技巧:子序列的构成不是简单地“逐段分割”,而是将 相隔某个增量dk的记录组成一个子序列,让增量dk逐趟 缩短(例如依次取5,3,1),直到dk=1为止。 优点:让关键字值小的元素能很快前移,且序列若基本 有序时,再用直接插入排序处理,时间效率会高很多。
称为外部排序。
注:外部排序时,要将数据分批调入内存来排序,中间 结果还要及时放入外存,显然外部排序要复杂得多。
5.待排序记录在内存中怎样存储和处理? ① 顺序排序——排序时直接移动记录; ② 链表排序——排序时只移动指针; ③ 地址排序——排序时先移动地址,最后再移动记录。
注:地址排序中可以增设一维数组来专门存放记录的地址。
}
}
16
表插入排序算法分析:
① 无需移动记录,只需修改2n次指针值。但由于比较次 数没有减少,故时间效率仍为O(n2) 。
相关文档
最新文档