1、数 据 结 构DATA STRUCTURE引言引言基本概念和术语基本概念和术语数据类型、数据类型、C C语言的数据类型语言的数据类型算法的描述和分析算法的描述和分析第一章 绪论21.1 什么是数据结构?一、讨论范畴思考:计算机的工作过程?对输入的数据数据进行各种处理处理,最后得到运算结果的过程。所以计算机科学是研究数据表示和数据处理的科学。程序程序=数据结构数据结构+算法算法u程序:为计算机处理问题编制一组指令集。u算法:为解决问题而采取的方法、步骤。u数据结构:问题的数学模型。反映数据的内部构成,即有哪些成分构成,各成分之间关系,呈现的结构状态。例1:数据库中的表结构;例2:操作系统中文件系
2、统结构:目录树以非数值计算为主的应用中,算法与数据的重要性关系发生变化。二、数据结构在计算机科学中的地位“学生学生”表格表格特点:由一条条学生记录组成,各记录按学号大小递增排特点:由一条条学生记录组成,各记录按学号大小递增排列,形成一对一线性关系,称为线性表列,形成一对一线性关系,称为线性表UNIX文件系统的系统结构图特点:采用多级目录的目录树形式组织文件。特点:采用多级目录的目录树形式组织文件。具有一对多层次关系。具有一对多层次关系。引言引言基本概念和术语基本概念和术语数据类型、数据类型、C C语言的数据类型语言的数据类型算法的描述和分析算法的描述和分析第一章 绪论61.2 基本概念和术语一
3、、一、几个概念几个概念1.数据:数据:数据是信息的载体,是描述客观事物的数、字符、以及所有能输入到计算机中,被计算机程序识别和处理的符号符号的集合。分为:数值性数值性数据和非数值性数据数据和非数值性数据,如字符、图象、语音等。2.2.数据元素(数据元素(记录、结点记录、结点):):是数据处理的最小单位,有时一个数据元素由若干数据项(是数据不可分割的最小单位)组成,如一个学生记录由学号、姓名等数据项组成。数据对象:是具有相同性质的数据数据元素的集合。如:整数数据对象 N=0,1,2,3.3.数据结构数据结构(狭义、广义概念)狭义:数据元素之间的相互关系关系称为结构;相互之间存在一种或多种关系的数
4、据元素的集合称为数据结构。记为:记为:Data-Structure=D,R 其中,D:性质相同(同类型)的数据元素的集合;R:各元素之间逻辑关系的有限集合(一种或多种关系)。广义:研究非数值计算的程序设计问题中,计算机的操作对象、它们之间的关系以及在计算机中的存储和操作的学科。二、数据结构的研究内容二、数据结构的研究内容1 1.逻辑结构逻辑结构:数据元素之间逻辑关系的描述。数据元素之间逻辑关系的描述。从解决问题的需要出发,为实现必要的功能所建立的数据结构,是面向用户的视图。分为两大类:线性结构、非线性结构。线性结构、非线性结构。四种基本结构:线性表、树、图、集合。线性表、树、图、集合。常用关系
5、图表示:2.2.物理结构(存储结构)物理结构(存储结构):是数据在计算机中的实现:是数据在计算机中的实现(存储映像),不仅存放数据数据本身,还要体现元素之间的关系关系。是面向计算机的视图。四种基本结构:顺序、链接、索引、散列存储结构四种基本结构:顺序、链接、索引、散列存储结构3.3.定义在定义在DSDS上的操作上的操作数据结构不仅要研究数据逻辑结构和物理结构,还包括定义在数据结构上的运算。即对数据的操作运算也是DS的研究内容。说明:算法与DS密不可分。一方面,好的算法建立在好的数据结构之上;另一方面,好的数据结构体现在算法中。即使逻辑结构相同,但定义的操作不同,则是不同的数据结构,如栈和队列。
6、基本操作:基本操作:插入、删除、更新、查找、排序等。插入、删除、更新、查找、排序等。说明:操作种类和数量无限制。但操作结果不能改变原结构。3.3.定义在定义在DSDS上的操作上的操作数据结构不仅要研究数据逻辑结构和物理结构,还包括定义在数据结构上的运算运算。即对数据的操作运算,也是DS的研究内容。说明:算法与算法与DSDS密不可分。密不可分。一方面,好的算法建立在好的数据结构之上;另一方面,好的数据结构体现在算法中。即使逻辑结构相同,但定义的操作不同,则是不同的数据结构,如栈和队列。基本操作:基本操作:插入、删除、更新、查找、排序等。插入、删除、更新、查找、排序等。说明:操作种类和数量无限制。
7、但操作结果不能改变原结构。总结:数据结构的研究内容总结:数据结构的研究内容(本课程的研究内容)(本课程的研究内容)u在解决问题时可能遇到的典型的逻辑在解决问题时可能遇到的典型的逻辑结构(数据结构)结构(数据结构)u逻辑结构的存储映象(存储实现)逻辑结构的存储映象(存储实现)u数据结构的相关操作及其实现。数据结构的相关操作及其实现。引言引言基本概念和术语基本概念和术语数据类型、数据类型、C C语言的数据类型语言的数据类型算法的描述和分析算法的描述和分析第一章 绪论131.3 1.3 数据类型和抽象数据类型数据类型和抽象数据类型1.数据类型:是性质相同的值的集合值的集合,及定义在此集合上的一组操作
8、一组操作的总称。说明:说明:规定了值的取值范围,和定义在此值上的操 作。是高级语言层次上对数据的抽象。例,C语言中的数据类型:基本数据类型(int、float、char)、数组、指针、结构体类型等。数据类型是高级语言中系统实现的数据结构,在在高级语言层次上讨论数据结构必须借助其数据类高级语言层次上讨论数据结构必须借助其数据类型来描述。型来描述。2.2.抽象数据类型抽象数据类型(ADTs:Abstract Data Types)与数据类型是一个概念,只是其范畴更广,主要指由用户定义由用户定义,用以表示应用问题的数据模型:由基本的数据类型组成由基本的数据类型组成,并包括一组相关的操作并包括一组相关
9、的操作。即:ADT=ADT=数据数据+操作操作特点:将数据与操作的定义封装在一个模块中,更能体现数据结构与操作是紧密联系的整体。引言引言基本概念和术语基本概念和术语数据类型、数据类型、C C语言的数据类型语言的数据类型算法的描述和分析算法的描述和分析第一章 绪论161.1.4 4 算法描述和算法分析算法描述和算法分析一、算法描述一、算法描述1.1.算法定义算法定义:是为解决一个问题而采取的方法和步骤。方法和步骤。2.2.算法的描述算法的描述:自然语言、伪代码、程序语言(C+,C,PASCAL等语言)。本书采用C语言描述。二、性能分析与度量二、性能分析与度量1.1.评评价价算算法法主主要要考考虑
10、虑的的因因素素:正正确确性性、效效率率(存存储空间和运行时间开销)、可读性储空间和运行时间开销)、可读性、健壮性等、健壮性等.一个算法运行所需时间的长短、空间的大小具有非常重要的意义。算法效率的度量:时间复杂度、空间复杂度时间复杂度、空间复杂度2、时间复杂度分析、时间复杂度分析时间复杂度:是与时间复杂度:是与问题规模问题规模有关的量。有关的量。算法处理的数据元素个数称为问题的规模算法处理的数据元素个数称为问题的规模。如:在有n个学生记录的文件中查找名为张三的学生记录,则n即为问题规模。时间复杂度计算:时间复杂度计算:一个算法所耗费的时间,应该是该算法中每条语句的执行时间之和,而每条语句的执行时
11、间又是该语句的执行次数(频度)与该语句执行一次所需时间的乘积。假定每条语句一次执行的时间都是相同的,为单位时间。这样,一个算法的时间耗费就是该算法中所有语句的频度之和。简化计算:简化计算:一一般般以以关关键键操操作作(循循环环、递递归归)的的执执行行频频度度(一一般般与与问问题题规规模模有有关关)作作为为时时间间复复杂杂度度,时时间间复复杂杂度度是是关关键键操操作作执执行行频频度度函函数数,是是关关于于n的的函函数数,T(n)。当当问问题题规规模模n趋趋于于无无穷穷大大时时,把把时时间间复复杂杂度度T(n)的的数数量量级级(阶阶)称称为为算算法法的的渐渐进进时时间间复复杂杂度度(有有时简称为时
12、间复杂度)记为:时简称为时间复杂度)记为:O(n)。)。它它表表示示当当n充充分分大大时时,时时间间复复杂杂度度T(n)的的数数量量级级(最高阶),如(最高阶),如:O(2n3+4n2+4n+10)O(n3)常用语句阶的计算:常用语句阶的计算:1 1)若算法的执行时间是一个若算法的执行时间是一个与问题规模与问题规模n n无关无关的常数,如赋值、的常数,如赋值、比较等,则算法的时间复杂度为常数阶,记作比较等,则算法的时间复杂度为常数阶,记作T(nT(n)=O(1)=O(1)。2 2)选择执行的成分,如选择执行的成分,如 if if 语句的执行时间,决定于语句的执行时间,决定于then then
13、子子句、句、else else 子句子句耗时较多耗时较多的部分。的部分。3 3)一般情况下对循环语句只考虑一般情况下对循环语句只考虑循环体语句循环体语句的执行次数,而的执行次数,而忽略该语句中补长加一、终值判别等成份。忽略该语句中补长加一、终值判别等成份。一次循环,设循环次数一次循环,设循环次数n n O(n)嵌套循环,由嵌套循环,由最内层循环体语句最内层循环体语句执行频度决定,设两层执行频度决定,设两层(外层循环次数(外层循环次数n,内层,内层m)O(mn)并列循环,由循环次数最大的决定,设两并列循环,循环并列循环,由循环次数最大的决定,设两并列循环,循环次数分别为次数分别为n、m O(ma
14、x(m,n)4 4)很多算法的时间复杂度不仅与问题的规模有关,而且还与很多算法的时间复杂度不仅与问题的规模有关,而且还与它所处理的它所处理的数据集的初始状态数据集的初始状态(取值、排列取值、排列)有关。有关。例例1:求两个方阵的乘积:求两个方阵的乘积 CA*Bdefine n 自然数自然数MATRIXMLT(float Ann,float Bnn,float Cnn)int i,j,k;for(i=0;in;i+)for(j=0;jn;j+)Cij=0;/n*n for(k=0;kn;k+)Cij+=Aik*Bkj /n*n*n 时间复杂度为:时间复杂度为:例例2:x=0;y=0;for(k=
15、1;k=n;k+)x+;/nfor(i=1;i=n;i+)for(j=1;j=0)&Ai!=k)i-;return i;此问题不仅与规模此问题不仅与规模 n n 有关,有关,而且与数组而且与数组A A中各元素的取值中各元素的取值有关。有关。问题与规模问题与规模 n n 无关。无关。常数阶常数阶对数阶对数阶线性阶线性阶线性对数阶线性对数阶平方阶平方阶立方阶立方阶K K次方阶次方阶指数阶指数阶常见的时间复杂度,按数量级递增排列常见的时间复杂度,按数量级递增排列(越小越好越小越好):空间复杂度分析空间复杂度空间复杂度:描述算法消耗的存储空间。描述算法消耗的存储空间。一般只考虑辅助空间,忽略程序与输入
16、数据所占空间。辅助空间一般与问题规模有关,通常在递归算法递归算法中考虑空间复杂度分析。原地操作:辅助空间消耗是常量阶,O(1)。由于存储技术的飞速发展,空间复杂度分析所以重要性降低,另外,空间复杂度分析只对某些特殊算法(递归算法)重要。数据结构数据结构李 凯2013年11月第二章 线性表Page 282.1 线性表定义和运算2.2 顺序表2.3 链表(单链表)2.4 其他形式链表内容内容设置设置Page 292.1 2.1 线性表定义与运算线性表定义与运算定义定义定义:线性表L是由n个元素a1,a2,an组成的有限序列,记作L=(a1,a2,an),其中n0为表长度;当n=0时L为空表,记作L
17、=()。表结构。由于线性表是一组元素的序列,因此每个元素最多有一个直接前驱,最多有一个直接后继。例如:(,ai-1,ai,ai+1)元素个数。即表长度。取值为一个有限数。表中元素在不同场合可以有不同含义与类型。例如:大写字母表(A,B,Z);数字表(0,1,2,9);成绩表(张三,100),(李四,90),)【ai是一个结构体记录】Page 302.1 2.1 线性表定义与运算线性表定义与运算基本基本运算运算初始化线性表List_Initial(L):构造一个空的线性表L。求表长度List_Length(L):求表中元素的个数。按照序号取元素List_GetElement(L,i):取出表中序
18、号为i的元素。按值查询List_Locate(L,x):在线性表L中查找值为x的元素。若存在,则返回其地址;否则,返回一个不存在的地址值或标记。Page 312.1 2.1 线性表定义与运算线性表定义与运算基本基本运算运算插入元素List_Insert(L,i,x):在线性表L的第i个位置插入值为x的元素。如果表长度为n,则i应满足1in+1。删除元素List_Delete(L,i):删除线性表L中序号为i的元素。1in。说明:线性表更复杂的运算可以由基本运算组合。例如:删除表中值为x的元素,可以通过+实现。对于基本运算中,在确定为某种具体数据时也可能存在差异。Page 322.2 2.2 顺
19、序表顺序表概念概念顺序表:假设有一个足够大的连续的存储空间,则可将线性表中元素按照其逻辑次序依次存储到该存储空间,称由此得到的线性表为顺序表。(线性表的顺序存储方法)顺序表在具体实现时,一般用数组来对应一个连续的存储空间。设最多可存放maxlen个元素,则可用数值datamaxlen来存储数据。(注:maxlen的取值需要自己预判)由于线性表中数据元素个数可能会发生变化,及表长度变化,因此线性表只占据了data的一部分,因此需设置一个变量记录顺序表元素个数。Page 332.2 2.2 顺序表顺序表概念概念#definemaxlen100/假设元素个数最大为100typedefstructEl
20、ement_Typedatemaxlen;/定义存储数值intlistlen;/定义表长度seqlist;seqlistL,L1;seqlistPage 342.2 2.2 顺序表顺序表基本基本运算运算初始化线性表:voidList_Initial(seqlist*L)L-listlen=0;求表长度:intList_Length(seqlistL)returnL.listlen;Page 352.2 2.2 顺序表顺序表基本基本运算运算按照序号取元素(取出的元素放在变量x里):voidList_GetElement(seqlistL,inti,Element_Typex)if(iL.list
21、len)error(“超出范围”);elsex=L.datai-1;Page 362.2 2.2 顺序表顺序表基本基本运算运算按值查询:intList_Locate(seqlistL,Element_Typex)inti;for(i=0;ilistlen=maxlen)error(“overflow”);elseif(iL-listlen-1)error(“positionerror”);elsefor(j=L-listlen-1;j=i-1;j-)L-dataj+1=L-dataj;/向后整体移动L-datai-1=x;/在第i个位置插入内容L-listlen+;/修改表长Page 392.
22、2 2.2 顺序表顺序表基本基本运算运算删除元素List_Delete(L,i):如果能从顺序表L中删除第i个元素ai,则需要依次执行下列操作:将ai+1an依次向前移动一个元素的位置,从而将ai“挤掉”。修改表的长度(表长度减1)。注意:第步移动时需要从ai+1开始,依次向后操作直到将an向前移动一个元素位置。移动过程与插入元素时移动方向恰好相反。Page 402.2 2.2 顺序表顺序表基本基本运算运算删除元素List_Delete(L,i):voidList_Delete(seqlist*L,inti)intj;if(L-listlen=0)error(“下溢出错”);elseif(iL
23、-listlen)error(“positionerror”);elsefor(j=i;jlistlen-1;j+)L-dataj-1=L-dataj;/向前整体移动L-listlen-;/修改表长Page 412.2 2.2 顺序表顺序表应用应用例1:假设线性表L元素递增有序,设计算法在该表中插入元素x,要求插入后L仍递增有序。从后往前找voidList_Insert_1(seqlist*L,Element_Typex)inti=L-listlen-1;if(i=maxlen-1)error(“overflow”);elsewhile(i=0&L-dataix)L-datai+1=L-dat
24、ai;i-;L-datai+1=x;L-listlen+;Page 422.2 2.2 顺序表顺序表应用应用例2:假设线性表L元素递增有序,设计算法在该表中删除重复的元素。求解方法分析:设变量i从头开始依次指示表中各元素以搜索其后继中的同值元素。每当i指向一个元素时,可能会有如下几种操作:若该元素已经到了表尾,无后继,则求解结束。若datai=datai+1,则应删除datai+1中的元素。否则,当前元素的同值元素搜索结束,需要转向下一个元素的搜索。Page 432.2 2.2 顺序表顺序表应用应用例2:假设线性表L元素递增有序,设计算法在该表中删除重复的元素。voidList_Delete_
25、1(seqlist*L)inti=1,j;while(ilistlen-1)/第i个元素还有后继if(L-datai=L-datai+1)for(j=i+2;jlistlen-1;j+)L-dataj-1=L-dataj;/向前整体移动L-listlen-;/修改表长elsei+;/转入下一个元素的同值元素搜索Page 442.2 2.2 顺序表顺序表应用应用练习1.上述例2中,若顺序表元素不是递增的,如何设计算法实现同值元素删除?练习2.上述例2也可以采用另一种方法:将每一个搜索到需要保留的元素放到表的左边连续空间中。自己实现。练习3.假设线性表A、B分别表示一个集合,设计算法判断集合A是不
26、是集合B的子集。若是,返回1;否则返回0.练习4.设计算法将递增有序的顺序表A和B中的元素合并为一个递增有序的顺序表C。练习5.结合教材内容,思考上述算法的时间复杂度。Page 452.3 2.3 链表链表概念概念链表:线性表的链接存储方式。结点结构示意图:结点由两部分组成,即存放元素值的部分和存放后继元素地址的部分,从而使得物理位置不相邻的元素逻辑上具有先后次序关系。由于通过地址将元素链接起来,因此将这种线性表称为链表。Page 462.3 2.3 链表链表概念概念静态链表:用数组来存储元素的值和地址。在程序执行过程中数组元素个数固定,因此成为静态链表。后继next中存放数组下标即可。Pag
27、e 472.3 2.3 链表链表概念概念动态链表:在事先难以估计线性表中元素个数或为了节省空间,可以根据实际问题需要临时、动态地分配存储空间,即每个结点都是程序运行时所产生的动态变量,因此称为动态链表。typedefstructElement_Typedata;/存放数据的字段structnode*next;/指向后继元素的指针node;Page 482.3 2.3 链表链表概念概念把指向表头结点的指针称为头指针。从而可以定义动态链表变量:node*head;例如:*head;(*head).next也可写作head-next;a1a2a3 anHeadPage 492.3 2.3 链表链表概
28、念概念第i元素位置插入:s-next=p-next;p-next=s;表头(第1个元素位置插入):s-next=head;head=s;带头结点的单链表:优点:各结点操作统一。【不做特殊说明,一般指带头结点的单链表】Page 502.3 2.3 链表链表基本基本运算运算初始化线性表:voidList_Initial(node*head)head=(node*)malloc(sizeof(node);/产生头结点head-next=NULL;/设置后继指针为空Page 512.3 2.3 链表链表基本基本运算运算求表长度:在链表中,求表长度需要逐一数出元素个数。intList_Length(no
29、de*head)intn=0;node*p=head-next;while(p!=NULL)n+;p=p-next;return(n);Page 522.3 2.3 链表链表基本基本运算运算按照序号取元素(取出的元素放在变量x里):node*List_GetElement(node*head,inti)node*p=head;intj=0;while(j!=i&p!=NULL)p=p-next;j+;return(p);Page 532.3 2.3 链表链表基本基本运算运算按值查询:node*List_Locate(node*head,Element_Typex)node*p=head-nex
30、t;while(p!=NULL&p-data!=x)p=p-next;return(p);Page 542.3 2.3 链表链表基本基本运算运算插入元素:voidList_Insert(node*head,inti,Element_Typex)node*p=head;intk=0;node*s;while(k!=i-1&p!=NULL)p=p-next;k+;if(p=NULL)error(“序号错误!”);elses=(node*)malloc(sizeof(node);s-data=x;s-next=p-next;p-next=s;Page 552.3 2.3 链表链表基本基本运算运算删除
31、元素List_Delete(L,i):voidList_Delete(node*head,inti)node*u,*p;p=List_GetElement(head,i-1);if(p=NULL|p-next=NULL)error(“序号错误”);elseu=p-next;p-next=u-next;free(u);Page 562.3 2.3 链表链表应用应用例1.设计算法判断链表中元素是否递增。若递增,则返回1,否则,返回值0。intdzpd(node*head)node*p=head-next;if(p=NULL)return(1);while(p-next!=NULL)if(p-dat
32、anext-data)p=p-next;elsereturn(0);return(1);Page 572.3 2.3 链表链表应用应用例2.设递增有序的链表head表示一个集合,插入值为x的元素结点,仍保持递增有序。(假设无重复元素)voidList_Insert_2(node*head,Element_Typex)node*u,*p=head;while(p-next!=NULL&p-next-datanext;if(p-next=NULL|p-next-data!=x)u=(node*)malloc(sizeof(node);u-data=x;u-next=p-next;p-next=u;
33、Page 582.3 2.3 链表链表应用应用例3.设计算法复制链表A中的内容到B表中。voidList_Copy(node*A,node*B)node*p=A-next,*r,*u;B=(node*)malloc(sizeof(node);r=B;/设置B的尾指针while(p!=NULL)u=(node*)malloc(sizeof(node);u-data=p-data;r-next=u;r=u;p=p-next;r-next=NULL;/尾结点的后继指针置NULLPage 592.3 2.3 链表链表应用应用练习1.将链表A中的元素复制到链表B中,使得B表元素与A表元素次序相反。练习2.将链表A中的元素复制到链表B中,使得B表元素递增有序。练习3.假设链表A、B分别表示一个集合,设计算法判断集合A是不是集合B的子集。若是,返回1;否则返回0.练习4.设递增有序的链表A和B中分别表示
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1