【软考】【软件设计师】【知识模块】【第3章:数据结构】

第三章:数据结构:

数据结构是程序设计的重要基础

学会数据结构的目的:

  学会从问题出发,分析和研究计算机加工的数据的特性,

  以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法;

  【对于一个数据结构,需要考虑三个因素:逻辑结构、存储结构、运算方法(操作方法)】

  为提高利用计算机解决问题的效率服务;

  数据结构是指:数据元素的集合及元素间的相互关系和构造方法。

    元素间的相互关系:数据的逻辑结构

    元素间关系的存储:存储结构(或称之为 物理结构)

    

  数据结构的分类:

    线性结构

    非线性结构

      又分为树结构、图结构;

  

  数据结构是算法设计的基础。

  线性结构:线性结构主要用于对客观世界中具有单一前驱和后继的数据关系进行描述。

    线性表

      按照存储方式分类:

        采用顺序存储:用一组地址连续的存储的存储单元  依次存储线性表中的数据元素,

          现象:逻辑上相邻的两个元素,在物理位置上也相邻。

          优点:可以随机存取表中的元素,即可以对数据随机访问。

          缺点:插入和删除需要移动其他元素;(有时的移动量挺大)

          特点:

            各个结点的空间应该需要事先分配完毕,后续不论是否有数据,这个空间都不会变化,指导删除整个数据结构为止。

        

        采用链式存储:用   通过指针链接起来的结点    来存储数据元素;

          基本结构:数据源 和指针域;每个结点都有这两项;

            数据域用于存储数据元素的值;

            指针域则存储当前元素的直接前驱 或 直接后继的位置信息。指针域中的信息称为  指针(或链)

          特点:存储各个元素的节点的物理地址并不要求是连续的。

            在存储元素的同时,必须要存储元素的逻辑关系。

            结点空间只有在需要申请的时候才会被申请,无需事先分配。

            需要一个头指针head,指向第一个结点,就可以顺序的访问到表中的任意一个元素。

            链式存储的线性表,需要删除或插入时,实际只是针对指针的修改,数据域没有做必要的修改。

            在实际应用中,为了简化对链表状态的判定和处理,特别引入一个不存储数据元素的结点,称之为头结点,将其作为链表的第一个结点并令头指针指向该节点。

          缺点:不能对数据元素进行随机访问

          有点:插入和删除操作,不需要移动元素。

          单链表的查找、插入、删除运算,参考P102

          

          其他几种链式存储结构:

            双向链表:每个结点包含有两个指针,一个是直接前驱,一个是直接后继。

              特点:可以从表中任意结点出发,遍历整个链表。

            循环链表:在单向链表(或双向链表)的基础上,令表尾结点的指针指向链表的第一个结点,构成循环链表。

              特点:可以从任何节点开始遍历整个链表。

            静态链表:借助数组来描述线性表的链式存储结构,用数组元素的下标来表示元素的所在节点指针。

          

      线性表的基本操作:插入、删除、查找;

        

  栈与队列

    逻辑结构和线性表相同;

    特点:运算有所限制;

      栈:先进性出 LIFO

      队列:先进后出  FIFO

    栈:

      只能通过访问一端来实现数据存储和检索的一种线性数据结构。

      栈顶:进行插入和删除的一端

      栈底:与栈顶对应的另一端

      空栈:不含数据元素的栈

      栈的运算:

        初始化栈InitStack(S) :创建一个空栈

        判断空栈 isEmpty(S):当栈为空时,返回“真”,否则返回“假”

        入栈Push(S,x):将元素x加入栈顶,并更新栈顶指针。

        出栈Pop(S):将栈顶的元素从栈中删除,并更新栈顶的指针。

          若需要得到栈顶的值,可将Pop(S)定义为一个返回栈顶元素值的函数。

        Top(S):返回栈顶元素的值,但不修改栈顶指针。

      疑问:

      栈的元素个数是由栈顶指针定义的吗?栈内的元素类型是怎么规范定义的?

      初始化栈,会定义栈的空间大小。

    

      栈的存储结构:

        顺序存储

          一组地址连续的存储的存储单元  依次存储自栈顶到栈底的数据元素。

          设指针top指示栈顶元素的位置。

          需要预定义(或申请)栈的存储空间,

        链式存储(链栈)

          用链表作为存储结构的栈

          不用设置链表的头指针,栈顶指针就是链表头指针。

        栈的应用

          典型应用:表达式求值、括号匹配等;

          在计算机语言的实现,也会用到栈。

          将递归过程转变为非递归过程的处理,栈也会有重要应用。

        

    队列:

      一种先进先出的线性表;

      先进先出 First In First Out;

      特性:

        只允许在一端插入元素,在另一端删除元素。

        允许插入元素的一端,称之为队尾(Rear)。

        允许删除元素的一端,称之为对头(Front)。

        对头和队尾各有一个指针。( 队头指针front 、队尾指针rear;)

      队列的基本运算:

        初始化队列InitQueue(Q):创建一个空的队列Q;

        判断空isEmpty(Q):当队列为空时,返回“真”,否则返回“假”。

        入队 EnQueue(Q,x):将元素x加入到队列Q的队尾,并更新队尾指针。

        出队DelQueue(Q):将对头元素从队列Q中删除,并更新对头指针。

        读队头元素FrontQue(Q) : 返回队头元素的值,但不更新对头的指针。

        队列的存储结构:

          顺序存储结构:(同其他顺序存储数据结构)

            为了降低运算的复杂度,元素入队只修改队尾指针;元素出队只修改对头指针。

              但由于顺序队列的存储空间容量是提前设定的,所以队尾指针会有一个上限值,当队尾指针达到该上限时,就不能只修改队尾指针来增加元素了。

            环形队列:(通过整除取余运算来实现。)

              可维持入队出队的操作运算的简单性。

              根据队列操作的定义,Q.rear == Q.front 时,即对头指针和队尾指针相等是,可能队列为空,也可能队列为满,显然这种情况会有问题。

                两种结局办法:1、设置一个标志位,当出现上述情况时,代表队列为空还是为满;

                       2、牺牲一个存储单元,约定:队列的尾指针所指的位置的下一个位置是队头指针时    表示队列满。(由此想到的一个问题,若队列长度为1,那么这个队列是不是永远不能插入元素?)

          队列的链式存储:(链队列)

            为了便于操作,给链队列添加了一个头结点,并令头指针指向头结点。

            队列为空的判断条件是:头指针和尾指针的值相同,并均指向头结点。

        队列的应用:

          常用于处理需要排队的场合,例如打印任务、离散事件的计算机模拟等

      

    串:

      字符串,是一种特殊的线性表;

      其元素为字符。

      运算时,常把一个串视作一个整体来处理。

    

      串,仅由字符构成的优先序列;

      串的几个概念:  

        空串:长度为0的串;

        空格串:由一个或多个空格组成的串。

        子串:由串中任意长度的连续字符构成的序列

          

        主串:含有子串的串           

          子串在主串的位置,是指  子串首次出现时,子串的第一个字符在主串中的位置。

          空串是任意串的子串。

        串相等:两个串的长度相等,且对应的序号的字符也相等;

        串比较:比较操作从两个串的第一个字符开始进行,字符的码值大者所在的串为大,比较字符的ASCII码值;

      串的基本操作:

        赋值操作 StrAssign(s,t) : 将串s 的值赋给串t  。

        连接操作Concat(s,t):j将串  t  接续在串s 的尾部,形成一个新的串;

        求串长StrLength(s):返回串s 的长度;

        串比较StrCompare(s,t):比较两个串的大小。

          返回值  -1,0,1 分别表示  s < t  、s = t 、 s > t   ;

        求子串SubString(s,strat,len):  返回串s 中 从start 开始的  、长度为len 的字符序列。

      串的存储结构:

        顺序存储结构:一组地址连续的存储单元   ,来存储串值的字符序列;

          由于串都是由字符构成,可通过程序语言提供的 字符数组  定义串的存储空间,

          也可以根据串长的需要动态申请字符串的空间。

        链式存储结构:用链表存储串中的字符。

          每个结点中可以存储一个字符,也可以存储多个字符。

          考虑到存储密度问题,节点大小的选择会直接影响到串的处理效率。

      串的模式匹配:子串的定位操作

        子串  也被称之为   模式串;

        朴素的模式匹配算法:   布鲁特--福斯算法;

        改进的模式匹配算法: KMP算法;

      

    数组、矩阵和广义表:

      数组、广义表  可看作是线性表的推广。

        数据元素仍然是一个表;

      

      数组:定长线性表在维数上的扩展。

        线性表中的元素又是一个线性表。

        n维数组是一种“同构”的数据结构,其每个数据元素类型相同、结构一致。

        数组结构的特点:

          元素数目固定,一个被定义的数组,其元素个数固定。

          元素具有相同的类型。

          下标关系具有上下界的约束,且下标有序;

        数组的基本运算:

          给定一个下标,存取相应的数据元素。

          给定一个下标,修改相应的数据元素中某个数据项的值。

        数组的顺序存储:

          数组一般不做插入和删除运算,一旦定义了数组,则结构中的数据元素个数和元素之间的关系就不再发生变动,因此数组适合采用顺序存储结构。

        

      矩阵:

        数据结构中,主要关注的是:如何在节省存储空间的情况下使矩阵的各种运算能高效地进行。

          压缩存储:在一些矩阵中,存在很多值相同的元素或者0元素,为了节省存储空间,可以对这类矩阵进行压缩存储。

            多个值相同的元素只分配一个存储单元,0不分配存储单元。

          特殊矩阵:值相同的元素(或0元素)在矩阵中的分布有一定的规律

          稀疏矩阵:与特殊矩阵相对,无规律分布;

        

      广义表:线性表的推广;

        广义表和线性表的区别:

          广义表的元素既可以是单元素、也可以是有结构的表。

          线性表的元素都是结构上不可分的单元素。

        广义表一般记为:     

        

        

        广义表的属性:

          广义表的长度:广义表中元素的个数

          广义表的深度:广义表展开后所含的括号的最大层数。

        

        广义表的基本操作:

          取表头:head(LS)  :非空广义表的第一个元素就是表头;

          取表尾:tail(LS)  :非空广义表中,除表头以外,其他元素所构成的表称为表尾。

          

  

  

          


      【关于#####的一些特性,后续再补充吧,参考书籍P#####】

    

————————(我是分割线)————————

参考:

1. 《软件设计师教程》(第五版,清华大学出版社,禇华、霍秋艳 主编)

2.  赛迪网校 :www.ccidedu.com(教学视频资源)

3. 美河学习在线团购组:www.eimhe.com (教学视频来源)

4.  

备注:

初次编辑时间:2019年10月30日15:31:32

环境:Windows 7   / Python 3.7.2 

猜你喜欢

转载自www.cnblogs.com/kaixin2018/p/11767093.html