ImageVerifierCode 换一换
格式:DOCX , 页数:88 ,大小:1.31MB ,
资源ID:12177012      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12177012.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(NOIP高中信息技术竞赛资料数据结构.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

NOIP高中信息技术竞赛资料数据结构.docx

1、NOIP高中信息技术竞赛资料数据结构第1章 绪论程序设计就是使用计算机解决现实世界中的实际问题。对于给定的一个实际问题,在进行程序设计时,首先要把实际问题中用到的信息抽象为能够用计算机表示的数据;第二要把抽象出来的这些数据建立一个数据模型,这个数据模型也称为逻辑结构,即建立数据的逻辑结构;第三要把逻辑结构中的数据及数据之间的关系存放到计算机中,即建立数据的存储结构;最后在所建立的存储结构上实现对数据元素的各种操作,即算法的实现。本章就是要使大家了解计算机中的数据表示,理解数据元素、逻辑结构、存储结构和算法的有关概念;掌握基本逻辑结构和常用的存储方法,能够选择合适的数据的逻辑结构和存储结构;掌握

2、算法及算法的五个重要特性,能够对算法进行时间复杂度分析,从而选择一个好的算法,为后面的学习打下良好的基础。1.1基本概念和术语1.数据(data):是对客观事物的符号的表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。2.数据元素(data element):是数据的基本单位,在计算机程序中通常作为一个整体来处理。一个数据元素由多个数据项(data item)组成,数据项是数据不可分割的最小单位。3.数据结构(data structure):是相互之间存在一种或多种特定关系的数据元素的集合。数据结构是一个二元组,记为:data_structure=(D,S).其中D为数据元素的集合,

3、S是D上关系的集合。数据元素相互之间的关系称为结构(structure)。根据数据元素之间关系的不同特性,通常由下列四类基本结构:(1)集合:数据元素间的关系是同属一个集合。(图1)(2)线性结构:数据元素间存在一对一的关系。(图2)(3)树形结构:结构中的元素间的关系是一对多的关系。(图3)(4)图(网)状结构:结构中的元素间的关系是多对多的关系。(图4) 图1 图2 图3 图41.2 数据的逻辑结构和物理结构1.逻辑结构:数据元素之间存在的关系(逻辑关系)叫数据的逻辑结构。即上面给出的四种结构。2.物理结构:数据结构在计算机中的表示(映象)叫数据的物理结构,又称存储结构。一种逻辑结构可映象

4、成不同的存储结构:顺序存储结构和非顺序存储结构(链式存储结构和散列结构)。1.3算法及算法分析1. 算法:是对特定问题求解步骤的一种描述,是指令的有限序列。一个算法是一系列将输入转换为输出的计算步骤。 2. 算法的重要特性 输入:一个算法应该有零个或多个输入。 有穷性:一个算法必须在执行有穷步骤后正常结束,而不能形成无穷循环。 确定性:算法中的每一条指令必须有确切的含义,不能产生多义性。 可行性:算法中的每一条指令必须是切实可执行的,即原则上可以通过已经实现的基本运算执行有限次来实现。 输出:一个算法应该有一个或多个输出,这些输出是同输入有某个特定关系的量。 3. 算法的时间复杂度定义:设问题

5、的规模为n,把一个算法的时间耗费T(n)称为该算法的时间复杂度,它是问题规模为n的函数。算法的渐进时间复杂度设T(n)为一个算法的时间复杂度,如果当n趋向无穷大时T(n)与函数f(n)的比值的极限是一个非零常数M,即记作T(n)=O(f(n),则称O(f(n)为算法的渐进时间复杂度,简称时间复杂度,也称T(n)与f(n)的数量级相同,通常,f(n)应该是算法中频度最大的语句的频度。常用的算法的时间复杂度的顺序O(1)O(lgn)O(n)O(nlgn)O(n2)O(n3)=0&(Ai!=k)(3)i-;(4)return i;此算法中的语句(3)的频度不仅与问题规模n有关,还与输入实例中A的各元

6、素取值及K的取值有关:若A中没有与K相等的元素,则语句(3)的频度f(n)=n;若A的最后一个元素等于K,则语句(3)的频度f(n)是常数0。 最坏时间复杂度和平均时间复杂度最坏情况下的时间复杂度称为最坏时间复杂度。一般不特别说明,讨论的时间复杂度均是最坏情况下的时间复杂度。这样做的原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的上界,这就保证了算法的运行时间不会比任何情况下更长。平均时间复杂度是指所有可能的输入实例均以等概率出现的情况下,算法的期望运行时间。 例1 求下列交换两个变量i和j的值的算法的时间复杂度。 (1) i=10; (2) j=20; (3) t=i; (4)

7、 i=j; (5) j=t;解:各行语句的执行次数均为1,所以该算法的时间耗费T(n)= 1+1+1+1+1=5,该算法的时间耗费T(n)与问题的规模n无关,因此,该算法的时间复杂度T(n)=O(1)。例2 求两个n阶方阵的乘积C=AB,其算法如下,计算该时间复杂度。程序段:(1) for(i=0; in; i+)(2) for(j=0; jn; j+)(3) cij=0;(4) for(k=0; kn; k+)(5) cij+=aik*bkj; 解:解法1计算程序段中的每一行的执行次数。第(1)行for(i=0; in; i+)中只考虑循环条件表达式in的执行次数(忽略初始化表达式i=0和修

8、正表达式i+的执行次数,下同),表达式in共执行n+1次(i为0到n-1时该表达式非零,共n次,i为n时该表达式为零,共1次,合计执行n+1次),所以,第(1)行共执行n+1次;第(2)行for(j=0; jn; j+),在第(1)行for(i=0; in; i+)中的表达式in非零时(共n次)都要执行一遍,而每一遍同样要执行n+1次,所以,第(2)行共执行n(n+1)次;第(3)行cij=0;在表达式in和jn均非零时执行,共执行n2次;第(4)行for(k=0; kn; k+)在表达式in和jn均非零时执行一遍,而每一遍同样要执行n+1次,所以,第(4)行共执行n2(n+1)次;第(5)行

9、cij+=aik*bkj; 在表达式in、jn和kn均非零时执行,共执行n3次;因此,各行执行次数分别为:n+1,n(n+1),n2,n2(n+1),n3。如果用T(n)表示该算法的时间耗费,则 T(n)= n+1+n(n+1)+n2+n2(n+1)+n3=2n3+3n2+2n+1由此可知,该算法的时间耗费T(n)是矩阵阶数n的函数,T(n)=O(n3)。解法2只计算执行频度最高的行。显然,在该程序段中,执行频度最高的行为cij+=aik*bkj; 在表达式in、jn和kn均非零时执行,而表达式in、jn和kn均有n次非零,所以,该行共执行n3次。因此,该算法的时间耗费T(n)是矩阵阶数n的函

10、数,T(n)=O(n3)。【课堂实践】分析并计算下面程序段执行的时间复杂度。i=1; k=0;while(i0,则除a1和an外,有且仅有一个直接前驱和一个直接后继,即ai(其中1 in)是线性表中第i个数据元素,在ai之前仅有一个数据元素ai-1,而在ai之后也仅有一个数据元素ai+1。称a1称为起始结点,an称为终端结点,i称为ai在线性表中的序号或位置。线性表中结点的之间的关系就是上述的邻接关系,由于该关系是线性的,我们称线性表是一种线性结构。2.线性表的基本运算(1)线性表初始化格式:InitList(L)初始条件:线性表L不存在。操作结果:构造一个空的线性表L。(2)求线性表的长度格

11、式:LengthList(L)初始条件:线性表L存在。操作结果:返回线性表L中所有元素的个数。(3)取表元格式:GetList(L,i)初始条件:线性表L存在,且1iLengthList(L)。操作结果:返回线性表L的第i个元素(ai)的值。(4)按值查找格式:LocateList(L,x)初始条件:线性表L存在,x有确定的值。操作结果:在线性表L中查找值为x的数据元素,并返回该元素在L中的位置。若L中有多个元素的值与x相同,则返回首次找到的元素的位置;若L中没有值为x的数据元素,返回一个特殊值(通常为-1)表示查找失败。(5)插入操作格式:InsertList(L,i,x)初始条件:线性表L

12、存在,i为插入位置(1in+1,n为插入前的表长)。操作结果:在线性表L的第i个元素(ai)位置上插入值为x的新元素,原序号为i,i+1, ,n的数据元素的序号插入后变为i+1,i+2, ,n+1,插入后表长=原表长+1。(6)删除操作格式:DeleteList(L,i)初始条件:线性表L存在,i(1in)为给定的待删除元素的位置值。操作结果:在线性表L中删除序号为i的数据元素(ai),删除后,原序号为i+1,i+2, ,n的数据元素的序号变为i,i+1, ,n-1,删除后表长=原表长-1。注:以上给出的是线性表的基本运算,并不是全部运算,其它运算可用这些基本运算来实现,这些运算都是定义在逻辑

13、结构层次上的运算,只有确定了存储结构之后,才能具体实现这些运算。例1 假设两个线性表LA,LB分别代表两个集合A和B:求A=A U Bvoid union(List &La ,List &Lb)/将所有在线性表Lb中,但不在La中的数插入到La中La.len=ListLength(La);Lb.len=ListLength(Lb); /求两表的长度for(i=1;i=Lb.len;i+) GetElem(Lb,i,e);/取Lb中第i个的元素复制给eIf(!LocateElem(La,e,equal)ListInsert(La,+La.len,e);/若其中不存在相同的,则插入/union例2

14、 已知线性表la,lb中的数据元素按值非递减有序排列,现要求将la,lb归并为一个新的线性表lc且lc按值非递减。例如 la=(3,5,8,11), Lb=(2,6,8,9,11,15,20)则lc=(2,3,5,6,8,8,9,11,11,15,20)分析:由于两表都是按照一定顺序进行排列,所有设置2个指针,分别指向a、b表,先分别比较比较最初指向的两数据,比较一下大小,谁小就放入到c表中,然后数小的指针向下移动,再进行比较。直到2表有一表结束,再将剩余的表存放到c中。Void MergeList(List La, List Lb,List &Lc)/已知线性表la和lb中的数据元素Init

15、List(Lc);/初始化表cInt i=j=1;k=0;La.len=ListLength(La);Lb.len= ListLength(Lb);While(i= La.len)&( (j= Lb.len)GetElem(La,i,ai);GetElem(Lb,j,bj);/获取数值If(ai=bj)ListInsert(Lc,+k,ai);i+;elseListInsert(Lc,+k,bj);j+;/if结束/whie结束,其中一表结束;While(i=La.len)/表B数据全访问完,表a未到最后GetElem(La,i+,ai);ListInsert(Lc,+k,ai);While(

16、j=Lb.len)/表a数据全访问完,表b未到最后GetElem(Lb,j+,bj);ListInsert(Lc,+k,bj);/程序结束分析:上述2个算法的时间复杂度(基本操作的执行时间),例1为O(ListLength(La)*ListLength(Lb),例2的时间复杂度为O(ListLength(La)+ListLength(Lb)。2.2 线性表的顺序存储结构线性表的顺序存储即用一组地址连续的存储单元依次存储线性表中的元素。设线性表中每个元素需占用r个存储单元则 loc(ai+1 )=loc(ai)+r loc(ai)=loc(a1)+(i-1)*r线性表的这种机内表示称做线性表的顺

17、序存储结构或顺序映像,通常,称这种存储结构的线性表为顺序表。只要确定了存储线性表的起始位置,线性表中任一数据元素可随机存储,所以线性表的顺序结构是一种随机存储的存储结构。/=线性表的动态顺序存储结构#define LIST_INIT_SIZE 100 / 初始分配量#define LISTINCREMENT 10 /分配增量Typedef structElemtype *elem; /存储空间基址Int length; /当前长度Int listsize; /当前分配的存储容量SqList;Elem表示基地址,length指示线性表的当前长度。上述的含义是为顺序表分配一个预定义大小的数据空间,

18、并将当前的长度设为0;Status InitList_sq(SqList &L)/=创建一个空的线性表L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType);/ ElemType指数据类型,malloc新分配空间If(!L.elem) exit(OVERFLOW);/存储分配失败L.length=0;/空表长度为0L.listsize= LIST_INIT_SIZE;/初始存储容量Return ok;/InitList_sq在这种存储方式下,容易实现对表的遍历。要在表的尾部插入一个新元素,也很容易。但是要在表的中间位置插入一个新元素,就

19、必须先将其后面的所有元素都后移一个单元,才能腾出新元素所需的位置。Status ListInsert_sq(SqList &L,int I,ElemType e)/在顺序表中插入一个新元素 eIf(iL.length+1) return Error;If(L.length= L.listsize)/当前存储空间已满,增加分配Newbase=(ElemType*)realloc(L.elem,(LIST_INIT_SIZE+LISTINCREMENT)*sizeof(ElemType);/ ElemType指数据类型,realloc再次分配,L.elem存储基地址/ifq=&(L.elemi-1

20、);/q为插入位置for(p=&(L.elemL.length-1);p=q;-p)*(p+1)=*q;/for*q=e;/插入e+ L.length;Return ok;执行删除运算的情形类似。如果被删除的元素不是表中最后一个元素,则必须将它后面的所有元素前移一个位置,以填补由于删除所造成的空缺。这两种运算的时间复杂度均为O(n)n为表的长度。Status ListDelete_sq(SqList &L,int I,ElemType &e)/在顺序表中插入一个新元素 eIf(iL.length+1) return Error;p=&(L.elemi-1);/p为删除位置e=*p;q=L.el

21、em+L.length-1;for(+p;pnext=p-next; p-next=s;上述算法中,链表指针的修改情况见图2图2(a)是执行Insert运算之前的情况。我们要在指针p所指的单元之后插入一个新元素x。图2(b)是执行Insert运算以后的结果,其中的虚线表示新的指针。在上述Insert算法中,位置变量p指向单链表中一个合法位置,要插入的新元素x应紧接在p所指单元的后面。指针p的合法性应在执行Insert运算之前判定。往一个单链表中插入新元素通常在表头或表尾进行,因此p的合法性容易判定。Insert运算所需的时间显然为O(1)。(2)Delete(p)功能:从表L中删除位置p的下一

22、元素。例如,当L为a1,a2,an时,执行Delete(p)后,L变为a1,a2,ap-1,ap+1,an 。当L中没有位置p或p=End(L)时,该运算无定义。实现:p.next=p.next.next;这个过程很简单,其指针的修改如图3所示。若要从一个表中删除一个元素x,但不知道它在表中的位置,则应先用Locate(x,L)找出指示要删除的元素的位置,然后再用Delete删除该位置指示的元素。Delete过程所需的时间显然也为O(1)。2.静态链表静态链表:用游标指示数组单元地址的下标值,它属整数类型数组元素是记录类型,记录中包含一个表元素和一个作为游标的整数;具体说明如下:type ji

23、d=record data:datatype; next:integer; end;var alist=array0.maxsize of jid游标即我们可以用游标来模拟指针, 对于一个表L,我们用一个整型变量Lhead(如Lhead=0)作为L的表头游标。这样,我们就可以用游标来模拟指针,实现单链表中的各种运算。当i1时,表示第i个位置的位置变量pi的值是数组alist中存储表L的第i-1个元素next值,用p:=alist(p).next后移。照此,我们虽然是用数组来存储表中的元素,但在作表的插人和删除运算时,不需要移动元素,只要修改游标,从而保持了用指针实现表的优点。因此,有时也将这种

24、用游标实现的表称为静态链表。3.循环链表循环链表是另一种链式存储结构,特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。因此,可由表中任一结点出发均可找到表中其他结点。如图6所示的是一个单链的循环链表或简称为单循环链表。(a)非空表(b)空表图6单循环链表在单循环链表上实现表的各种运算的算法与单链表的情形是类似的。它们仅在循环终止条件上有所不同:前者是p或p.next指向表头单元;后者是p或p.next指向空(nil)。在单链表中我们用指向表头单元的指针表示一个表L,这样就可以在O(1)时间内找到表L中的第一个元素。然而要找到表L中最后一个元素就要花O(n)时间遍历整个链表。在单循环链表中,我们也可以用指向表头单元的指针表示一个表L。但是,如果我们用指向表尾的指针表示一个表L时,我们就可以在O(1)时间内找到表上中最后一个元素。同时通过表尾单元中指向表头单元的指针,我们也可以在O(1)时间内找到表L中的第一个元素。在许多情况下,用这种表示方法可

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1