C语言数据结构

1.什么是数据结构

       一般来说,用计算机解决一个具体问题时,大致需要经过下列几个步骤:首先要从具体问题抽象出一个适当的数学模型,然后设计一个解此数学模型的算法,最后编出程序,进行测试,调整直至得到最终解答。寻求数学模型的实质是分析问题,从中提取操作的对象,并找出这些操作对象之间含有的关系,然后用数学的语言加以描述。例如,求解梁架结构中应力的数学模型为线性方程组;预报人口增长情况的数学模型为微分方程。然而,更多的非数值计算问题无法用数学方程加以描述。下面请看3个例子。

      例1-1图书馆的书目检索系统自动化问题。当你想借阅一本参考书但不知道书库中是否有的时候;或者,当你想找某一方面的参考书而不知图书馆内有哪些这方面的书时,你都需要到图书馆去查阅图书目录卡片。在图书馆内有各种名目的卡片:有按书名编排的,有按作者编排的,还有按分类编排的,等等。若利用计算机实现自动检索,则计算机处理的对象便是这些目录卡片上的书目信息。列在一张卡片上的一本书的书目信息可由登录号、书名、作者名、分类号、出版单位和出版时间等若干项组成,每一本书都有惟一的一个登录号,但不同的书目之间可能有相同的书名v或者有相同的作者名v或者有相同的分类号。由此,在书目自动检索系统中可以建立一张按登录号顺序排列的书目文件和3张分别按书名、作者名和分类号顺序排列的索引表,如图1.1所示。由这4张表构成的文件便是书目自动检索的数学模型,计算机的主要操作便是按照某个特定要求(如给定书名)对书目文件进行查询。诸如此类的还有查号系统自动化、仓库账目管理等。在这类文档管理的数学模型中,计算机处理的对象之间通常存在着的是一种最简单的线性关系,这类数学模型可称为线性的数据结构。

       例1-2计算机和人对弈问题。计算机之所以能和人对弈是因为有人将对弈的策略事先已存入计算机。由于对弈的过程是在一定规则下随机进行的,所以,为使计算机能灵活对弈就必须对对弈过程中所有可能发生的情况以及相应的对策都考虑周全,并且,一个

C语言数据结构_第1张图片

 

        “好”的棋手在对弈时不仅要看棋盘当时的状态,还应能预测棋局发展的趋势,甚至最后结局。因此,在对弈问题中,计算机操作的对象是对弈过程中可能出现的棋盘状态——称为格局。例如图1.2(a)所示为井字棋的一个格局,而格局之间的关系是由比赛规则决定的。通常﹐这个关系不是线性的,因为从一个棋盘格局可以派生出几个格局,例如从图1.2(a)所示的格局可以派生出5个格局,如图1.2(b)所示,而从每一个新的格局又可派生出4个可能出现的格局。因此,若将从对弈开始到结束的过程中所有可能出现的格局都画在一张图上,则可得到-棵倒长的“树”。“树根”是对弈开始之前的棋盘格局,而所有的“叶子”就是可能出现的结局,对弈的过程就是从树根沿树权到某个叶子的过程。“树”可以是某些非数值计算问题的数学模型,它也是一种数据结构。

C语言数据结构_第2张图片

       例1-3多叉路口交通灯的管理问题。通常,在十字交叉路口只需设红,绿两色的交通灯便可保持正常的交通秩序,而在多叉路口需设几种颜色的交通灯才能既使车辆相互之间不碰撞,又能达到车辆的最大流通。假设有一个如图1.3(a)所示的五叉路口,其中C和E为单行道。在路口有13条可行的通路,其中有的可以同时通行,如A→B和E→C,而有的不能同时通行,如E→B和A→D。那么,在路口应如何设置交通灯进行车辆的管理呢?

C语言数据结构_第3张图片

 

       通常,这类交通、道路问题的数学模型是一种称为“图”的数据结构。例如在此例的问题中,可以图中一个顶点表示一条通路,而通路之间互相矛盾的关系以两个顶点之间的连线表示。如在图1.3(b)中,每个圆圈表示图1.3(a)所示五叉路口上的一条通路,两个圆圈之间的连线表示这两个圆圈表示的两条通路不能同时通行。设置交通灯的问题等价为对图的顶点的染色问题,要求对图上的每个顶点染一种颜色,并且要求有线相连的两个顶点不能具有相同颜色,而总的颜色种类应尽可能地少。图1.3(b)所示为一种染色结果,圆圈中的数字表示交通灯的不同颜色,例如3号色灯亮时只有D→A和D→B两条路可通行。

       综上3个例子可见,描述这类非数值计算问题的数学模型不再是数学方程,而是诸如表、树和图之类的数据结构。因此,简单说来,数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科。

       “数据结构"作为一门独立的课程在国外是从1968年才开始设立的。在这之前,它的某些内容曾在其他课程,如表处理语言中有所阐述。1968年在美国一些大学的计算机系的教学计划中,虽然把“数据结构”规定为一门课程,但对课程的范围仍没有作明确规定。当时,数据结构几乎和图论,特别是和表、树的理论为同义语。随后,数据结构这个概念被扩充到包括网络、集合代数论、格、关系等方面,从而变成了现在称之为《离散结构》的内容。然而,由于数据必须在计算机中进行处理,因此,不仅考虑数据本身的数学性质,而且还必须考虑数据的存储结构,这就进一步扩大了数据结构的内容。近年来,随着数据库系统的不断发展,在“数据结构”课程中又增加了文件管理(特别是大型文件的组织等)的内容。

       1968年美国唐·欧·克努特教授开创了“数据结构”的最初体系,他所著的《计算机程序设计技巧》第一卷《基本算法》是第一本较系统地阐述数据的逻辑结构和存储结构及其操作的著作。从20世纪60年代末到70年代初,出现了大型程序,软件也相对独立,结构程序设计成为程序设计方法学的主要内容,人们就越来越重视“数据结构”,认为程序设计的实质是对确定的问题选择一种好的结构,加上设计一种好的算法。从20世纪70年代中期到80年代初,各种版本的数据结构著作就相继出现。

       目前在我国“数据结构”也已经不仅仅是计算机专业的教学计划中的核心课程之一,而且是其他非计算机专业的主要选修课程之一。

       “数据结构"在计算机科学中是一门综合性的专业基础课。“数据结构”的研究不仅涉及到计算机硬件(特别是编码理论、存储装置和存取方法等)的研究范围,而且和计算机软件的研究有着更密切的关系,无论是编译程序还是操作系统,都涉及到数据元素在存储器中的分配问题。在研究信息检索时也必须考虑如何组织数据,以便查找和存取数据元素更为方便。因此,可以认为“数据结构”是介于数学.计算机硬件和计算机软件三者之间的一门核心课程(如图1.4所示)。在计算机科学中,“数据结构”不仅是一般程序设计(特别是非数值计算的程序设计)的基础,而且是设计和实现编译程序﹑操作系统﹑数据库系统及其他系统程序和大型应用程序的重要基础。

        值得注意的是,“数据结构”的发展并未终结,一方面,面向各专门领域中特殊问题的数据结构得到研究和发展,如多维图形数据结构等;另一方面,从抽象数据类型的观点来讨论数据结构,已成为一种新的趋势,越来越被人们所重视。

C语言数据结构_第4张图片

 

2.基本概念和术语

       在本节中,我们将对一些概念和术语赋以确定的含义,以便与读者取得“共同的语言”。这些概念和术语将在以后的章节中多次出现。

       数据(data)是对客观事物的符号表示,在计算机科学中是指所有能输人到计算机中并被计算机程序处理的符号的总称。它是计算机程序加工的“原料”。例如,一个利用数值分析方法解代数方程的程序,其处理对象是整数和实数;一个编译程序或文字处理程序的处理对象是字符串。因此,对计算机科学而言,数据的含义极为广泛,如图像、声音等都可以通过编码而归之于数据的范畴。

       数据元素(dataelement)是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。例如,例1-2中的“树”中的一个棋盘格局,例1-3中的“图”中的一一个圆圈都被称为一个数据元素。有时,一个数据元素可由若千个数据项(dataitem)组成,例如,例1-1中-本书的书目信息为一个数据元素,而书目信息中的每一项(如书名、作者名等)为一个数据项。数据项是数据的不可分割的最小单位。

        数据对象(data object) 是性质相同的数据元素的集合,是数据的一个子集。例如,整数数据对象是集合N={0,士1,士2,.*},字母字符数据对象是集合C={'A','B',..,'Z').

       数据结构(datastructure)是相互之间存在一种或多种特定关系的数据元素的集合。这是本书对数据结构的一-种简单解释中。从1.1节中3个例子可以看到,在任何问题中,数据元素都不是孤立存在的,而是在它们之间存在着某种关系,这种数据元素相互之间的关系称为结构(structure)。根据数据元素之间关系的不同特性,通常有下列4类基本结构:(1)集合结构中的数据元素之间除了“同属于一个集合”的关系外,别无其他关系9;(2)线性结构结构中 的数据元素之间存在一个对一个的关系;(3)树形结构结构中的数据元素之间存在一个对多个的关系;(4)图状结构或网状结构结构中 的数据元素之间存在多个对多个的关系。图1.5为上述4类基本结构的关系图。由于“集合”是数据元素之间关系极为松散的一种结构,因此也可用其他结构来表示它。

C语言数据结构_第5张图片

 

       数据结构的形式定义为:数据结构是--个二元组Data Structure= (D,S)其中: D是数据元素的有限集,S是D上关系的有限集。下面举两个简单例子说明之。

       例1-4在计算机科学中,复 数可取如下定义:复数是一种数据结构Complex = (C,R)其中: C是含两个实数的集合{c1,c2};R={P},而P是定义在集合C上的一种关系{),其中有序偶表示el是复数的实部,c2是复数的虚部。

       例1-5假设我们需要编制一个事务管理的程序,管理学校科学研究课题小组的各项事务,则首先要为程序的操作对象一课题小组 设计一个数据结构。假设每个小组由1位教师、1~3名研究生及1~6名本科生组成,小组成员之间的关系是:教师指导研究生,而由每位研究生指导一至两名本科生。则可定义以下数据结构:

C语言数据结构_第6张图片

       上述数据结构的定义仅是对操作对象的一种数学描述,换句话说,是从操作对象抽象出来的数学模型。结构定义中的“关系”描述的是数据元素之间的逻辑关系,因此又称为数据的逻辑结构。然而,讨论数据结构的目的是为了在计算机中实现对它的操作,因此还需研究如何在计算机中表示它。.数据结构在计算机中的表示(又称映像)称为数据的物理结构,又称存储结构。它包.括数据元素的表示和关系的表示。在计算机中表示信息的最小单位是二进制数的- -位,叫做位(bit)。在计算机中,我们可以用一个由若干位组合起来形成的-个位串表示一个数据元素(如用一个字长的位串表示一个整数,用8位二进制数表示-个字符等) ,通常称这个位串为元素D(element)或结点(node)。当数据元素由若干数据项组成时,位串中对应于各个数据项的子位串称为数据域(datafield)。因此,元素或结点可看成是数据元素在计算机中的映像。

       数据元素之间的关系在计算机中有两种不同的表示方法:顺序映像和非顺序映像,并由此得到两种不同的存储结构:顺序存储结构和链式存储结构。顺序映像的特点是借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系。例如,假设用两个字长的位串表示一个实数,则可以用地址相邻的4个字长的位串表示一个复数,如图1. 6(a)为表示复数z1=3.0-2.3i和z2=-0.7+4.8i的顺序存储结构;非顺序映像的特点是借助指示元素存储地址的指针(pointer)表示数据元素之间的逻辑关系,如图1.6(b)为表示复数z1的链式存储结构,其中实部和虚部之间的关系用值为“0415”的指针来表示(0415是虚部的存储地址)中。数据的逻辑结构和物理结构是密切相关的两个方面,以后读者会看到,任何一个算法的设计取决于选定的数据(逻辑)结构,而算法的实现依赖于采用的存储结构。

C语言数据结构_第7张图片

       如何描述存储结构呢。虽然存储结构涉及数据元素及其关系在存储器中的物理位置,但由于本书是在高级程序语言的层次上讨论数据结构的操作,因此不能如上那样直接以内存地址来描述存储结构,但我们可以借用高级程序语盲中提供的“数据类型”来描述它,例如可以用所有高级程序语言中都有的“一维数组"类型来描述顺序存储结构,以C语言提供的“指针”来描述链式存储结构。假如我们把C语言看成是一个执行C指令和C数据类型的虚拟处理器,那么本书中讨论的存储结构是数据结构在C虚拟处理器中的表示,不妨称它为虚拟存储结构。

        数据类型(datatype)是和数据结构密切相关的一个概念,它最早出现在高级程序语言中,用以刻画(程序)操作对象的特性。在用高级程序语言编写的程序中,每个变量、常量或表达式都有一个它所属的确定的数据类型。类型明显或隐含地规定了在程序执行期间变量或表达式所有可能取值的范围,以及在这些值上允许进行的操作。因此数据类型是一个值的集合和定义在这个值集上的一组操作的总称。例如,C语言中的整型变量,其值集为某个区间上的整数(区间大小依赖于不同的机器),定义在其上的操作为加、减、乘、除和取模等算术运算。

       按“值”的不同特性,高级程序语言中的数据类型可分为两类:-类是非结构的原子类型。原子类型的值是不可分解的,例如C语言中的基本类型(整型、实型、字符型和枚举类型)、指针类型和空类型。另一类是结构类型。结构类型的值是由若干成分按某种结构组成的,因此是可以分解的,并且它的成分可以是非结构的,也可以是结构的。例如数组的值由若干分量组成,每个分量可以是整数,也可以是数组等。在某种意义.上,数据结构可以看成是“一组具有相同结构的值",则结构类型可以看成由一种数据结构和定义在其上的一组操作组成。实际上,在计算机中,数据类型的概念并非局限于高级语言中,每个处理器0(包括计算机硬件系统.操作系统、高级语言、数据库等)都提供了一-组原子类型或结构类型。例如,一个计算机硬件系统通常含有“位”、“字节”、“字”等原子类型,它们的操作通过计算机设计的--套指令系统直接由电路系统完成,而高级程序语言提供的数据类型,其操作需通过编译器或解释器转化成低层,即汇编语言或机器语言的数据类型来实现。引入“数据类型”的目的,从硬件的角度看,是作为解释计算机内存中信息含义的一种手段,而对使用数据类型的用户来说,实现了信息的隐蔽,即将一切用户不必了解的细节都封装在类型中。例如,用户在使用“整数”类型时,既不需要了解“整数”在计算机内部是如何表示的,也不需要知道其操作是如何实现的。如“两整数求和" ,程序设计者注重的仅仅是其“数学上求和”的抽象特性,而不是其硬件的“位”操作如何进行。

       抽象数据类型(Abstract Data Type,简称ADT)是指一个数学模型以及定义在该模型上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关,即不论其内部结构如何变化,只要它的数学特性不变,都不影响其外部的使用。.抽象数据类型和数据类型实质上是-一个概念。例如,各个计算机都拥有的“整数”类型是一个抽象数据类型,尽管它们在不同处理器上实现的方法可以不同,但由于其定义的数学特性相同,在用户看来都是相同的。因此,“抽象”的意义在于数据类型的数学抽象特性。

       另一方面,抽象数据类型的范畴更广,它不再局限于前述各处理器中已定义并实现的数据类型(也可称这类数据类型为固有数据类型),还包括用户在设计软件系统时自己定义的数据类型。为了提高软件的复用率,在近代程序设计方法学中指出,--个软件系统的框架应建立在数据之上,而不是建立在操作之上(后者是传统的软件设计方法所为)。即.在构成软件系统的每个相对独立的模块上,定义一组数据和施于这些数据上的-组操作,并在模块内部给出这些数据的表示及其操作的细节,而在模块外部使用的只是抽象的数据和抽象的操作。显然,所定义的数据类型的抽象层次越高,含有该抽象数据类型的软件模块的复用程度也就越高。

       一个含抽象数据类型的软件模块通常应包含定义、表示和实现3个部分。

       如前所述,抽象数据类型的定义由一个值域和定义在该值域上的一组操作组成。若按其值的不同特性,可细分为下列3种类型:

       原子类型(atomicdatatype)属原子类型的变量的值是不可分解的。这类抽象数据类型较少,因为一般情况下,已有的固有数据类型足以满足需求。但有时也有必要定义新的原子数据类型,例如数位为100的整数。

       固定聚合类型(fixed-aggregatedatatype)属该类型的变量,其值由确定数目的成分按某种结构组成。例如,复数是由两个实数依确定的次序关系构成。

       可变聚合类型(variable-aggregate data type)和固定聚合类型相比较,构成可变聚合类型“值”的成分的数目不确定。例如,可定义-一个“有序整数序列”的抽象数据类型,其中序列的长度是可变的。

       显然,后两种类型可统称为结构类型。

       和数据结构的形式定义相对应,抽象数据类型可用以下三元组表示

其中,D是数据对象,S是D上的关系集,P是对D的基本操作集。本书采用以下格式定义抽象数据类型:C语言数据结构_第8张图片

其中,数据对象和数据关系的定义用伪码描述,基本操作的定义格式为

 

       基本操作有两种参数:赋值参数只为操作提供输人值;引用参数以&打头,除可提供输人值外,还将返回操作结果。“初始条件”描述了操作执行之前数据结构和参数应满足的条件,若不满足,则操作失败,并返回相应出错信息。“操作结果”说明了操作正常完成之后,数据结构的变化状况和应返回的结果。若初始条件为空,则省略之。    

 例1-6抽象数据类型三元组的定义:

C语言数据结构_第9张图片

       多形数据类型(polymorphic data type)是指其值的成分不确定的数据类型。例如,例1-6中定义的抽象数据类型Triplet,其元素el、e2和e3可以是整数或字符或字符串,甚至更复杂地由多种成分构成(只要能进行关系运算即可)。然而,不论其元素具有何种特性,元素之间的关系相同,基本操作也相同。从抽象数据类型的角度看,具有相同的数学抽象特性,故称之为多形数据类型。显然,需借助面向对象的程序设计语言如C++等实现之。本书中讨论的各种数据类型大多是多形数据类型,限于本书采用类C语言作为描述工具,故只讨论含有确定成分的数据元素的情况。如例1-6中的ElemSet是某个确定的、将由用户自行定义的、含某个关系运算的数据对象。 

就先说这么多啦。下一篇我们再接着学剩下的。如有任何问题,欢迎与我联系。需要C语言入门大礼包、各种C语言C++学习资料的小伙伴可以加入小编的学习圈,里面聚集了一些正在学习C语言的小伙伴,在学习C语言的过程中遇到任何的问题,大家都可以一起交流,大家可以根据自己需要领取源码素材。希望大家都能够实现自己的梦想,加油!大家可以根据自己需要领取源码素材!

 点击链接加入群聊【C语言/C++学习交流群icon-default.png?t=M276https://jq.qq.com/?_wv=1027&k=4vU0kUSM  】:

你可能感兴趣的:(c语言,c++)