数据结构专题——那些难以理解的数据结构基本概念

本贴最后更新于 2438 天前,其中的信息可能已经事过景迁

不知有没有人和博主一样,在上大学的时候最头疼的一门课就是数据结构与算法了,其中枯燥的概念、冗长的伪代码都让博主昏昏欲睡。

尤其是严大妈在《数据结构》中开篇讲述的数据结构、数据类型与抽象数据类型的概念,让博主完美地将这三个概念混淆了很久(这里没有黑严大妈的意思……但是数据结构确实给当时没有认真听课的博主留下了深刻的印象)。

博主希望在这个系列的博文中将自己眼中的数据结构与各位同学进行分享,希望大牛们能不吝赐教或是对初学者能有一点帮助。

在本篇博文中我主要谈谈我对以下三个概念的理解,欢迎大家与我一起讨论。

  • 数据结构
  • 数据类型
  • 抽象数据类型

首先来看数据结构的概念:

数据结构: 是相互之间存在一种或多种特定关系的数据元素的集合。这种结构可以是逻辑结构或者是物理结构

逻辑结构是指数据之间的逻辑关系,比如

  • 当所有数据都属于一个集合,而彼此之间没有别的关系时,这就是逻辑上的集合关系,如下图;

c25091822d4541918a8b13f87773cf48-2017102821.11.48.png

  • 当数据之间有下图所展示的一一对应的关系时,就属于线性结构
    ceacc21e91f54dad9047fdca4835f8a2-2017102821.24.04.png

  • 当数据之间有下图所展示的一对多的关系时,就属于树形结构
    663d1a8bf22a46fe8ffee8be8c576860-2017102821.25.42.png

  • 当数据之间有下图所展示的多对多的关系时,就属于图形结构
    2fb5453f54464a8aacdac735766e1acb-2017102821.26.50.png

物理结构是指数据如何计算机中存储的形式

若数据被存放在连续的存储单元中,则属于顺序存储结构,这种数据结构中数据间的逻辑关系和物理关系是一致的。这种数据结构很简单,最常见的例子就是数组。当我们向计算机申请创建一个装有 10 个整型元素的数组时,计算机会在内存中找一块连续的空间,按照一个整型元素所需的内存大小乘以 10,为这个数组开辟所需的内存空间,其中第一个元素放在第一个位置,第二个元素放在第二个位置,依次摆放,如下图所示。

d6e8c50c58844f36bccc2b9c270983e0-2017102821.43.12.png

若数据被存放在任意的存储单元中,则属于链式存储结构,这种数据结构中的数据存放位置可以是连续的,也可以是不连续的。数据间的存储关系并不能反应它的逻辑关系,因此需要指针来存放元素的位置,这样通过地址就可以找到相关联元素的位置了,如下图所示。
ec1a2da5af3a4a67a4a46be266ced158-2017102821.47.38.png

根据上述的概念来看,我们平常所说的树(Tree)、线性表(List)、图(Graph)都属于数据结构,因为它们的元素满足逻辑结构中元素的特定逻辑关系。

同样,以 Java 语言为例,ArrayList(基于数组实现的线性表)、LinkedList(链表)也属于数据结构,因为他们的元素在计算机中是以顺序与链式的物理结构来存储的。

逻辑结构是面向逻辑关系的结构,而物理结构是面向计算机存储的结构。对于我们程序员来说我们更倾向于关注物理结构,因此我们更习惯叫 ArrayList 这种线性表的实现为数据结构。

接下来我们来看数据类型的概念:

数据类型:是指一组性质相同的值的集合及在此集合上的一些操作的总称。

同样以 Java 语言为例,每一个变量在被声明的时候我们都需要指明它的数据类型。因为内存需要知道你这个数据应该被分配多大的空间。

同样的一个变量 i=12, 如果它被声明为 byte 类型就会被分配 8 bits 的空间,而被声明为 int 类型就会被分配 32 bits 的空间。

通常来说,数据类型分为原子类型结构类型

原子类型就是不可再分的基本类型:整型、浮点型等等

结构类型就是由若干个原子类型组成符合类型。

以 Java 为例,原子类型就是 8 个基本数据类型,而结构类型就是引用类型。对于 C 语言、或是 C++ 而言,原子类型就是基本类型,结构类型就是 struct。

但是不同的硬件系统在将这些数据类型转换为底层语言时肯定会有不同。这点对于 C 语言来说尤为明显,比如 int 类型没有固定的取值范围,而是依赖于硬件系统来决定。

因此这些我们人为为数据划定的“类型”就有硬件的局限性了。

这也是抽象数据类型出现的原因。

抽象数据类型:是指一个数据模型及定义在该模型上的一组操作

抽象数据类型可以解决上述 int 类型在不同硬件上有不同取值的问题。

比如说,我们可以抽象出一个数据类型叫做整型。那么在任何硬件系统中需要用到的整数类型以及整数的操作都可以在这个抽象类型中声明。至于在某种编程语言中将它实现为 32 位的 int 类型还是 16 位的 int 类型抽象类型都不需要关心。

以 Java 语言为例,线性表 List 是一个抽象数据类型;但 ArrayList 与 LinkedList 就不是抽象数据类型,因为这两种具体的数据结构已经是线性表的具体实现了,并不具有抽象性。

三者的关系总结

  • 数据结构数据类型的关系

数据结构是由一个个的数据元素组成的,而这些数据在声明的时候都会属于某一种数据类型。

  • 数据结构抽象数据类型的关系

逻辑数据结构一般也可以看作抽象数据类型;但物理数据结构不是抽象数据类型,而是抽象数据类型的具体实现。

  • 数据类型抽象数据类型的关系

数据类型是人为规定的平台相关的类型;而抽象数据类型是将数学模型和模型的相关操作抽象出来

注:本文图片来源于程杰老师的《大话数据结构》

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    130 引用 • 793 回帖
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 234 关注
  • abitmean

    有点意思就行了

    29 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 2 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 1 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 433 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    140 引用 • 441 回帖 • 1 关注
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    60 引用 • 287 回帖
  • 反馈

    Communication channel for makers and users.

    124 引用 • 907 回帖 • 210 关注
  • 电影

    这是一个不能说的秘密。

    120 引用 • 597 回帖
  • danl
    89 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    19 引用 • 23 回帖 • 699 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 336 关注
  • BND

    BND(Baidu Netdisk Downloader)是一款图形界面的百度网盘不限速下载器,支持 Windows、Linux 和 Mac,详细介绍请看这里

    107 引用 • 1281 回帖 • 31 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 531 关注
  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    163 引用 • 473 回帖
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 383 回帖 • 4 关注
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    45 引用 • 113 回帖 • 284 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 608 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    165 引用 • 407 回帖 • 514 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1425 引用 • 10043 回帖 • 474 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 111 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖