数据结构学习之路--谈谈本人对数据结构的认识及理解

哈喽啊~又和大家见面啦!今天我想分享一下:个人对数据结构的理解及其重要性。

目录

前言 

一、为什么说数据结构很重要

二、什么是数据结构

三、数据类型

四、数据的逻辑结构 

五、数据的存储结构 

1 基本存储结构

2 常见的数据结构(逻辑结构)对应的存储结构 

3 数据的运算集合 


 

前言 

   不瞒你们说,我在学数据结构之前,潜意识里总是觉得数据结构的知识似乎没什么太大用处,在我们日常的编程中,除了特意去想要实现数据结构的相关算法,基本涉及不到有用到数据结构知识去解决问题的地方。其实不然,数据结构是软件开发中最基础最重要的理论基础。

一、为什么说数据结构很重要

    首先,我们为什么要开发各种各样的软件,其目的只有一个:利用计算机来为人类处理各种数据并以一定的形式展现出来供用户使用。随着计算机应用范围的不断发展,计算机所需要处理的数据也越来越复杂,并且规模越来越大,计算机所处理的数据已经不再是单纯的数值数据,而更多的是非数值数据。

   其次,现实中所需要处理的数据并不是杂乱无序的。它们之间存在一定的内在联系,但这些联系往往都需要算法设计人员去总结、归纳、建模,然后抽象出一个具体的模型表示出来,我们将这个模型成为数据的逻辑结构。进而设计师们再围绕这个创建的逻辑结构总结出一套处理方法,这样以来,数据有了,模型有了,算法有了,在理论上的问题便可以解决了。剩下的就交给计算机去实现了,但以上都是基于逻辑上的设计,计算机并不懂得这些。所以接下来还需要对应的存储结构来把需要处理的的数据先存储到计算机中,再把那些处理逻辑(算法)用相应的代码实现出来,最后计算机才能对数据进行有效的处理。

二、什么是数据结构

   数据结构:即人们抽象出来的描述现实世界实体的数学模型(非数值计算)及其的相关操作(运算),在计算机上的表示和实现。

   数据结构就是指按一定的逻辑结构组成的一批数据,使用某种存储将这批数据存储于计算机中,并在这些数据上定义了一个运算集合。 

三、数据类型

   数据类型:定义该类型涵盖的数据的性质、取值范围以及对数据所能进行的各种操作。程序中的每一个数据都属于一种数据类型,决定了数据的类型的同时也知道了数据的性质以及对数据进行的各种运算和操作,当然,数据也会受到类型的保护,从而以免对数据进行非法操作。

   抽象数据类型(ADT):是指一个数学模型以及定义在该模型上的一组操作。抽象数据类型和数据类型本质上是一个概念,它们都表现数据的抽象特征。数据抽象是指“定义和实现相分离”,即把一个类型上的数据及操作的逻辑含义与具体的实现分离。程序设计语言提供的数据类型是抽象的,仅描述数据的特征和对数据操作的语法规则,并没有说明这些数据类型是如何实现的。程序设计语言实现了它预定义数据类型的各种操作,编程人员按照语言提供的规则使用数据类型,只考虑对数据执行什么操作(做什么),而不必考虑怎样实现这些操作(怎样做)。对于使用数据类型的用户来说,数据类型实现了信息的隐蔽,即将一切用户不必了解的细节都封装在类型中。例如C语言的类型--整数类型即是一个抽象数据类型,编程人员在使用整型时,并不需要知道其是如何实现的。 

   此外,抽象数据类型的范畴更广,它不再局限于程序语言已定义并实现的数据类型(也可称这类数据类型为固有数据类型),还包括编程人员在设计软件系统时自己定义的数据类型。

   如前所述,抽象数据类型的定义是由一个值域和定义在该值域上的一组操作组成,算法设计时,编程人员通常需要为一些抽象出来的逻辑结构来自定义一个抽象数据类型,比如:为线性表,栈,队列,串,广义表,二叉树,树,图等自定义抽象类型。一种抽象数据类型描述一种数据结构的逻辑特性和操作,与该数据结构在计算机内存储及实现无关。 

   抽象数据类型的三要素:数据对象,数据关系,基本操作。

   在实际应用中,编程人员在使用自定义的抽象数据类型之前,必须实现这些抽象数据类型(在实现之前,还应该为属于数据类型的数据元素定义结点),才能使用它们。而实现抽象数据类型依赖于数据存储结构。例如,线性表可分别采用顺序存储结构或链式存储结构来实现。 

四、数据的逻辑结构 

数据的逻辑结构是独立于计算机的,它与数据在计算机中的存储无关。数据的逻辑结构指数据元素之间的逻辑关系,分四种:集合,线性结构、树型结构、图状结构。再具体一些:线性表,栈,队列,串,广义表,树,图等都是对现实实体的抽象出来的逻辑结构。

下面我们来画图进行充分理解: 

  • 集合:结构中的数据元素之间除了“同属一个集合”的关系之外,没有任何关系。
  • 线性结构:结构中的数据元素之间只存在一对一的关系。
  • 树型结构:结构中的数据元素之间存在一对多的关系。
  • 图状结构或网状结构:结构中的数据元素之间存在多对多的关系。 

    数据元素:是数据的基本单位,在计算机程序中通常做为一个整体进行考虑和处理。数据元素可以是一个不可分割的原子项,也可以由多个数据项组成。数据项是数据元素中有独立含义的、不可分割的最小标示单位。

    例如,一个整数、一个字符都是原子项;一个学生的数据元素由学号、姓名、性别和出生日期等多个数据项组成。在计算机存储时,我们可以用一个由若干位组合起来形成的一个位串标示一个数据元素(如用一个字长的位串表示一个整数,用8位二进制数表示一个字符等),通常呈这个位串为元素或结点 。 

    五、数据的存储结构 

       我们想对数据进行处理,就必须将数据存储在计算机中。如果将数据在计算机中无规律地存储,那么在处理时是非常糟糕的,是没有用的。 

    下面我们来介绍数据的存储结构:

       数据结构在计算机中的表示(又称映像)成数据的物理结构,又称存储结构。它包括数据元素在计算机中的表示和关系的表示。 

    1 基本存储结构

    (1)  顺序存储:将逻辑上相邻的结点存储在一组连续的内存单元中,使得逻辑相邻的结点一定是物理位置相邻,元素在内存中的存储次序与它们的逻辑次序相同。顺序存储通常用于存储具有线性结构的数据,在高级程序设计语言中通常使用数组来实现。

    •  优点:实现随机存储,每个元素占用空间小。
    •  缺点:只能使用相邻的一整块存储单元,会产生较多的外部碎片。 

      (2)  链式存储:即使用若干地址分散的存储单元存储数据元素,逻辑上相邻的数据元素在物理位置上不一定相邻,数据元素之间的关系需要采用附加信息特别指定。通常,采用指针变量记载前驱或后继元素的存储地址,由数据域和地址域组成的一个结点表示一个数据元素,通过地址域把相互直接关联的结点链接起来,结点间的链接关系提仔数据元素间的逻辑关系。

      • 优点:不会出现碎片现象,充分利用所有的存储单元。
      • 缺点:每个元素要占用存储指针,需要多占用部分存储空间,而且只能顺序存取。 

        (3)  索引存储:在线性结构中,设开始结点的索引号为1,其它结点的索引号等于其前继结点的索引号加1,则每一个结点都有唯一的索引号,索引号就是根据结点的索引号确定该结点的存储地址。

        • 优点:检索速度快。
        • 缺点:增加索引表,占用较多存储空间,增删数据时也要修改索引表,花费较多的时间。 

          (4) 散列(哈希)存储:散列存储的思想是构造一个从集合K到存储区域M的一个函数h,该函数的定义域为K,值域为M,K中的每个结点ki在计算机中的存储地址由h(ki)确定。

          • 优点:检索,增删节点操作都很快。
          •  缺点:散列函数不好可能会出现元素存储单元的冲突,解决冲突会增加时间 ,空间的开销。 

            其中,顺序存储结构和链式存储结构是两种最基本、最常用的存储结构。除此之外,将顺序存储结构和链式存储结构进行组合,还可以构造出一些更加复杂的存储结构。

            2 常见的数据结构(逻辑结构)对应的存储结构 

            线性表的存储:线性表可以采用顺序存储结构和链式存储结构。采用顺序存储结构的链表称为顺序表,顺序表通常使用采用数组存储其数据元素,将线性表的数据元素顺序存放在数组中,数据元素在数组中的物理顺序与线性表中的元素的顺序关系完全相同。采用链式存储的线性表成为链表。

            栈的存储:顺序存储和链式存储两种,分别成为顺序栈和链栈;

            队列的存储:队列一般采用链式存储,其中循环队列可采用顺序存储;

            数组的存储结构:顺序存储,其中二维数组包括以行序为主序存储和以列序为主序存储:

               数组是顺序存储的随机存储结构,占用一组连续的存储单元,通过下标识别元素,元素地址是下标的线性函数。在程序设计语言中,数组已被实现为一种构造数据类型,程序语言中的整数类型,字符类型等都是基本数据类型,通过一个变量表示一个数据,这种变量称为简单变量。在实际应用中,经常需要处理具有相同性质的一批数据。

              例如要处理100个学生的考试成绩,如果要使用简单变量,将需要100个不同的变量,极为不便,为此,在C语言中,可以使用数组来存储着一批具有相同性质的数据。数组一旦占用一片存储空间,这片存储空间的地址和长度就是确定的,不能更改。

            结论:数组只能进行赋值、取值两种随机存取操作,不能进行插入、删除操作。

            我们来大致了解一下字符串的存储结构: 

            1.  定长顺序存储:类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列(比如使用一维数组存储)。
            2.  堆分配存储:仍以一组地址连续的存储单元存储串值的字符序列,但它们的存储空间是在程序执行过程中动态分配而得。
            3.  串的块链存储:可用链表的方式存储串值。 

            这里需要掌握:C语言中学过的数组,字符数组,字符串数组 ,以及有关于数据结构具体的相关内容,后续我会给大家更新的。

            矩阵的存储结构:高级语言编程时,通常都是用二位数组来存储矩阵元。矩阵存储时,我们感兴趣的不是矩阵本身,而是如何存储矩阵的元,从而使矩阵的各种运算能够有效的进行。矩阵式很多科学与工程计算问题中经常研究的数学对象。

            广义表的存储结构:通常采用链式存储结构。

            树的常用存储结构:双亲表示法存储、孩子链表存储、孩子兄弟表示法(又称二叉链表表示法)存储等,这几种存储方法都属于链式存储的不同方式。

            二叉树的常用存储结构:适用于完全二叉树的顺序存储结构、二叉链表存储、三叉链表存储法两种链式存储结构。

            图的常用存储结构:邻接矩阵表示法存储(数组表示法)、邻接表法、十字链表法、邻接多重表;其中邻接表法和十字链表法、邻接多重表都是图的不同链式存储方法。 

            3 数据的运算集合 

               数据操作指对一种数据结构中的数据元素进行各种运算或处理。每种数据结构都有一组数据操作。对于一批数据,数据的运算是定义在数据的逻辑结构之上的,而运算的具体实现就依赖于数据的存储结构。

               数据的运算集合要视情况而定,一般而言,数据的运算包括插入、删除、更新、检索、遍历、排序等。

            • 初始化、判断是否为空状态、统计数据元素个数
            • 插入:在一个结构中增加一个新的结点。
            • 删除:在一个结构删除一个结点。
            • 创作:创作一个结构中制定位置的结点。
            • 检索:在一个结构中查找满足条件的结点。
            • 输出:将一个结构中所有结点的值打印、输出。
            • 排序:将一个结构中所有结点按某种顺序重新排列。
            • 遍历:按某种次序访问所有元素,每个元素只能并且只能被访问一次,称为遍历操作。 

              简单概括,数据结构就是解决数据存储和数据操作的。数据存储就是怎样将现实中的一些事物在计算机中实现出来;数据操作就是模拟现实世界的一些操作。


              以上便是今天分享的全部内容,当然啦,这仅仅是数据结构的概况以及个人对数据结构的初步认识,未来我会针对数据结构持续更新其具体内容。如果大家觉得这篇文章对你们认识数据结构有所帮助,记得留下一个三连哈~博主也会竭尽所能地为大家带来更优质的创作!路虽远行则将至,事虽难做则必成,漫漫长路必见曙光!与君共勉!