数据结构(C语言版)

学习好难啊学不下去 2024-10-08 13:05:01 阅读 83

第一章        绪论

1.2        基本概念和术语

数据:所有能够输入到计算机中并被计算机程序处理的符号的总称

数据元素数据的基本单位,一个数据元素有若干个数据项组成

一本书的书目信息为数据元素,书目信息中的每一项(如书名,作者名等)为一个数据项

数据对象:性质相同的数据元素的集合,是数据的一个子集

数据结构:是相互之间存在一种或多种特定关系的数据元素的集合

结构:数据之间存在的各种关系

集合:除同属于一个集合外,无关系线性结构:一对一树形结构:一对多网状结构或图状结构:多对多

逻辑结构:结构定义中的“关系”描述的是数据元素之间的逻辑关系

物理结构(存储结构):数据结构在计算机中的表示(映像)

计算机中表示信息的最小单位是二进制中的一位,叫做

用一个由若干位组合起来形成的一个位串表示一个数据元素,称这个位串为元素或结点

当数据元素由若干数据项组成时,位串中对应于各个数据项的子位串成为数据域

顺序映像特点是借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系

元素之间位置相对固定

非顺序映像的特点是借助元素存储地址的指针表示数据元素之间的逻辑关系

用指针找位置

数据类型:是和数据结构密切相关的一个概念,是一个值的集合和定义在这个值集上的一组操作的集合

非结构的原子类型:原子类型的值不可分解结构类型:值是由若干成分按某种结构组成的,是可以分解的,成分为非结构或结构

抽象数据类型(ADT):指一个数学模型以及定义在该模型上的一组操作,其定义仅取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关,只要数学特性不变,都不影响其外部的使用

基本操作的定义格式:

基本操作名(参数表)

        初始条件:<初始条件描述>

        操作结果:<操作结果描述>

基本操作有两种参数:

赋值参数只为操作提供输入值;引用参数以&打头,除可提供参数值外,还将返回操作结果;&-->引用参数  /  返回结果

初始条件:描述了操作执行之前数据结构和参数应满足的条件,若不满足,则操作失败,并返回相应出错信息操作结果:说明了操作正常完成之后,数据结构的变化状况和应返回的结果。若初始条件为空,则省略之

第二章        线性表

2.1        线性表的类型定义

线性结构的特点是:在数据元素的非空有限集中,

存在唯一的一个被称为“第一个”的数据元素存在唯一的一个被称为“最后一个”的数据元素除第一个外,集合中的每个元素均只有一个前驱除最后一个外,集合中的每个元素均只有一个后继

线性表:最常用且最简单的一种数据结构,即一个线性表是n个数据元素的有限序列

在稍复杂的线性表中,一个数据元素可以由若干个数据项组成,在这种情况下,数据元素被称为记录,含有大量记录的线性表又称为文件同一线性表中的元素必定由相同的特性,即属于同一数据对象,相邻数据元素之间存在着序偶关系。线性表索引从1开始线性表中元素的个数n(n>=0)定义为线性表的长度,n=0时称为空表线性表中的元素有序排列,可以提高归并算法的时间效率

抽象数据类型线性表见书P19

2.2        线性表的顺序表示和实现

线性表的顺序:

指的是用一组地址连续的存储单元依次存储线性表的数据元素特点是,为表中相邻的元素赋以相邻的存储位置,相邻元素位置相邻线性表中的顺序存储结构是一种随机存取的存储结构

假设线性表的每个元素需占用L个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储位置。则线性表中第i + 1个数据元素的存储位置LOC(a[i+1])和第i个数据元素的存储位置LOC[a(i)]之间满足下列关系:

LOC(a[i+1]) = LOC(a[i]) + L

一般来说,线性表的第i个数据元素a(i)的存储位置为:

LOC(a[i]) = LOC(a[1]) + (i-1)L

LOC(a[1])是线性表的第一个数据元素a[1]的存储位置,通常称为线性表的起始位置或基地址

线性表的插入

一般情况下,在第 i (1<= i <= n)个元素之前插入一个元素时,需将第 n 至第 i (共n-i+1)个元素向后移动一个位置

线性表的删除

一般情况下,删除第  i 个元素时需要将从第 i + 1 至第 n 个元素依次向前移动一个位置

2.3        线性表的链式表示和实现

线性链表

线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素结点包括两个域,其中存储的信息称为数据域;存储直接后继存储位置的域称为指针域

指针域中存储的信息称为指针或链,n个结点链结成一个链表,即为线性表的链式存储结构。又由于此链表的每个结点中只包含一个指针域,故又称线性链表或单链表

线性表的线性链式存储结构,整个链表的存取必须从头指针开始进行,头指针指示链表中第一个结点(即第一个数据元素的存储映像)的存储位置。同时,由于最后一个数据元素没有直接后继,则线性链表中最后一个结点的指针为空用线性链表表示线性表时,数据元素之间的逻辑关系是由结点中的指针指示的单链表可由头指针唯一确定(头指针:指向链表中第一个结点)若线性表为空表,则头结点的指针域为空单链表中,任何两个元素的存储位置之间没有固定的联系,单链表是非随机存取的存储结构

线性表的插入与删除

线性表的插入:

在a,b两结点中插入数据元素x,首先生成一个数据域为x的结点,

然后实现,假设s为指向结点x的指针:

s -> next = p -> next;

p -> next = s;

线性表的删除

仅需修改结点a中的指针域:

p -> next = p -> next -> next;

在已知链表中元素插入或删除的确切位置的情况下,在单链表中插入或删除一个结点时,仅需修改指针而不需要移动元素

c语言中的标准函数malloc:

malloc函数(全称memory allocation函数),是C语言中进行内存动态分配的标准库函数,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址。

使用malloc函数,如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。

在c语言中,线性链表可用结构指针描述结点:

数据 + 下一个元素的位置(指针)。还可用数组的一个元素表示一个结点:数据 + 下一个元素的位置(数组下标)

静态列表

静态列表:用一维数组来描述线性列表

静态列表(与顺序表有两点不同):

每个元素包括数据域和指针域逻辑上相邻的数据元素存储位置可不相邻

循环列表

循环列表:是另一种形式的链式存储结构。特点:表中最后一个结点的指针域指向头结点,整个链表形成一个环。由此,从表中任一结点出发均可找到表中的其他结点。循环链表的操作和线性表基本一致,差别仅在于算法中的循环条件不是p或p->next 是否为空,而是它们是否等于头指针。尾结点p满足:p->next ==head

双向列表:在双向列表的结点中有两个指针域,其一指向直接后继,另一指向直接前驱

对于双向列表,在两结点之间插入一个新结点,需要修改共4个指针

有序链表的基本操作定义与线性链表有两处不同:

LocateElem的职能不同需增加按有序关系进行插入的操作OrderInsert

第三章        栈和队列

抽象数据类型栈的定义:

栈(又称后进先出的线性表):是限定仅在表尾进行插入或删除操作的线性表。

对栈来说,表尾端有特殊含义,称为栈顶;表头端称为栈底;不含元素的空表称为空栈

允许插入和删除的一端称为栈顶;另一端称为栈底

栈的基本操作除了在栈顶进行插入和删除之外,还有栈的初始化,判空及取顶元素等

栈的表现和形式:

顺序栈,即栈的顺序存储结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针 top 指示栈顶元素在顺序栈中的位置链栈:

采用单链表来存储栈中的元素只在链表头部进行插入和删除,不必设头结点链表的头指针就是栈顶指针

表达式求值:

任何一个表达式都是由操作数,运算符和界限符组成的,称它们为单词。一般地,操作数既可以是常数也可以是被说明为变量或常量的标识符;运算符可以分为算术运算符,关系运算符和逻辑运算符3类;基本界限符有左右括号和表达式结束符等

OPTR--用以寄存运算符;OPND--用以寄存操作数或运算结果

算法的基本思想是

首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕

栈与递归的实现

递归函数:一个直接调用自己或通过一系列的调用语句间接地调用自己的函数

迭代:通过某段代码的重复执行来实现循环

递归:通过重复调用函数自身来实现循环

通常,当在一个函数的运行期间调用另一个函数时,在运行被调用函数之前,系统需完成:

将所有的实在参数,返回地址等信息传递给被调用函数保存;为被调用函数的局部变量分配存储区;将控制转移到被调函数的入口。

背调函数返回调用函数之前,系统应完成;

保存被调函数的计算结果释放被调函数的数据区;依照被调函数保存的返回地址将控制转移到调用函数

当有多个函数构成嵌套调用时,按照“后调用先返回”的原则

队列

抽象数据类型队列的定义

队列是一种先进先出的线性表。只允许在表的一端进行插入,而在另一端删除元素在队列中,允许插入的一端叫做队尾;允许删除的一端则称为队头空队:不包含元素的空表队列中元素的插入和删除操作分别称为入队和出队双端队列:一种限定性数据结构。是限定插入和删除操作在表的两端进行的线性表超队列:删除一端,插入两端超栈:插入一端,删除两端双栈:那端插入的只能从该端删除

链队列——队列的链式表示和实现

链队列:用链表表示的队列一个链队列显然需要两个分别指示队头和队尾的指针(分别称为头指针和尾指针)才能唯一确定。为方便操作,给链队列添加一个头结点,并令头指针指向头结点。由此,空的链队列的判决条件为头指针和尾指针均指向头结点链队列的操作即为单链表的插入和删除操作等特殊情况,只是尚需修改尾指针或头指针。即,链队列的插入删除操作只需修改头尾指针

循环队列——队列的顺序表示和实现

在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外,尚需附设两个指针front 和rear 分别指示队列头元素及队列尾元素的位置初始化键空队列时,令front = rear =0,每当插入新的队列尾元素时,“尾指针增+1”;每当删除队列头元素时,“头指针+1”在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置有一循环队列Q,只凭Q.front = Q.rear 无法判别队列空间是“满”还是“空”。处理方法有:

另设一个标志位以区别队列是“空”还是“满”;少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(指环状的下一位置)上”作为队列呈“满”状态的标志

第四章        串

串类型的定义

串(字符串):是由零个或多个字符组成的有限序列        如:S = 'a1a2a3...an'(n>0)

其中S是串的名,用单引号括起来的字符序列是串的值,值可以是字母,数字或其他字符;

串中字符的数目n称为串的长度。零个字符的串称为空串,长度为零

串中任意个连续字符组成的子序列称为该串的字串。包含子串的串相应地称为主串。通常称字符在序列中的序号为该字符在串中的位置。子串在主串中的位置则以子串的第一个字符在主串中的位置来表示当且仅当两个串的值相等时,称这两个串是相等串值必须用一对单括号括起来,但单括号本身不属于串,它的作用只是为了避免与变量名或数的常量混淆而已由一个或多个空格组成的串称为空格串

串的表示和实现

定长顺序存储表示

串的顺序表示:用一组地址连续的存储单元存储串值的字符序列。在串的定长顺序存储结构中,按照预定义的大小,为每个定义的串变量分派一个固定长度的存储区超过预定长度的串值则被舍去,称之为截断对串有两种表示方式:

以下标为0的数组分量存放串的实际长度在串值后面加一个不计入串长的结束标记字符

(1)串联名Contact(&T,S1,S2)

T的前一段和串S1的值相等,串T的值的后一段和S2的值相等。基于串S1和S2长度的不同情况,串T值的产生可能有如下3种情况:

①S1[0]+S2[0]<=MAXSTRIEN,得到的串T是正确的结果;

②S1[0]<MAXSTRLEN而S1[0]+S2[0]>MAXSTRLEN,则将串S2的一部分截断,得到的串T只包含串S2的一个子串;

③S1[0]=MAXSTRLEN,则得到的串T并非联接结果,而和串S1相等

(2)求子串SubString(&Sub,S,pos,len)

求子串的过程即复制字符序列的过程,将串中从第pos个字符开始长度为len的字符序列复制到串Sub中。无截断,但要检验用户给出的参数是否符合操作的初始条件


在顺序存储结构中,实现串操作的原操作为“字符序列的复制”,操作的时间复杂度基于复制的字符序列的长度

堆分配存储表示

特点:仍以一组地址连续的存储单元存放串值字符序列,但它们的存储空间是在程序过程中动态分配而得。在C语言中,存在一个称为“堆”的自由存储区,并由C语言的动态分配函数malloc()和free()来管理。利用函数malloc()为每个新产生的 串分配一块实际串长所需的存储空间,若分配成功,则返回一个指向起始地址的指针,作为串的基址

串的快链存储表示

块链:用单链表示存储结构每个结点可以存放一个字符,也可以存放多个字符当结点大小大于1时,由于串不一定是结点大小的整数倍,则链表中的最后一个结点不一定全被串值占满,此时通常补上“#”或其他的非串值字符(通常“#”不属于串的字符集,是一个特殊的符号)由于一般情况下,



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。