数据结构的本质

1、生活、生产等现实世界的数据有各种各样的组成形式。例如一个课程的所有学生的成绩(一组数据),一个班全部学生的所有课程的成绩(一张表)、一个单位的人员结构(树)等等。 
2、这些数据都要先加载到内存中,再送到CPU中进行计算。 
3、内存的最基本单位叫做存储单元,一个字节(不讨论理论中的、个别情况的)。存储单元相当于一个空盒子,可以放置数据。为了便于管理,盒子会给一个编号,当然存储单元也会有编号,其实就是地址。理论上地址的方案可以有多种(计算机组成原理和操作系统的任务),不过对于程序员来说,这些都跟我们无关,为了简单起见,我们把存储单元的编号(地址)都编成0、1、2、3、4,……这样的,于是这些编号或地址的取值范围,我们就称地址空间。这个地址空间,跟一维坐标轴一样,所以是一维线性空间。 
4、很明显,数据就是一个个放入到这些存储单元中,就象我们把一个单位的物品放入盒子一样。现在,假设一个盒子只能装入一个单位的物品。因而,一个存储单元也只能放入一个单位的数据。 
5、接下来,假设说,我们有很多很多的空盒子(X个)。有一天,我们要将若干单位物品(N个)放入盒子中,那么我们可以在一个盒子放入一个单位物品。依此类推,我们可以在一个存储单元中放置一个单位的数据。 
6、再接下来,我们有两种放置方案:一个挨一个地连续地放置物品;当然,也可以不连续地放置物品。依此类推,在内存当中放置数据,也有两种方案,连续地放置数据,或者不连续地放置数据。为什么会有不连续的放置方案呢?原因很简单,一个主要的原因是,内存的空间利用率高,碎片少(操作系统的存储管理的知识,且不用理会),删除旧有的数据很容易(这个是数据结构的内容)。 
7、现在,可以把这两个将数据放入到存储单元的方案叫做物理存储。对连续物理存储方案来说,事情比较好办,通过编号(索引、下标)就可以找到物品,对于不连续的方案,那么我们就要在一个物品上面标记下一个物品的位置,这个标记就是下一个物品的地址(指针)。当然,在计算机中,指针的记录本身也要占用内存的存储单元,所以我们在C语言中用结构体把数据和指针组织成为一个单位。通过这个指向关系,我们可以在不连续的放置方案中依次地查找我们所需要的东西(物品或数据)。 
8、接下来,就象我们经常进行从盒子当中查询物品、取用物品或增加物品等操作一样,我们也要进行从内存当中查询数据、取用(删除)数据或增加数据等操作。那么,对于不同的物理存储方案来说,其方法是不一样的。这个想一想,我们如何对付真实的物品,我们就如何对付内存中的数据。这就是数据的物理存储方案的数据操作。 
9、好了,搞懂这些,字符串之类的知识点就不难了。 
10、记住一点,只有两种物理存储结构:连续的和不连续的,因为内存的存储单元的地址(编号)是0、1、2、3……(一维地址空间、或者线性地址空间)。 
11、是不是只有物理存储结构(方案)就可以了呢?在第1条中说过,现实当中的数据是有各种各样的结构的。而在第10条,我们强调了物理放置方案只有2种:连续的和不连续的。 
12、于是就产生一个问题,如何将现实世界当中的关系各种各样的数据放入到内存之中。 
13、解决第12条中的问题,我们可以分两步走,第1步是将现实世界的数据组织成为逻辑结构,第2步再把逻辑结构的数据映射到物理结构中。 
14、显然,在第1步中,我们抛去数据的其它属性,只留下数据的两个属性就可以了:一个属性是数据的值,另一个属性就是数据之间的关系。这两个属性就得到一个逻辑结构:graph(图),这就是离散数学中的图论。那么,这就是科学家的事情,他们负责针对具体的问题,将现实世界的数据构造出对应的graph(图)。 
15、在第2步中,我们要做的事情,把这个graph映射到物理存储结构中,这就是数据结构要做的事情了。显然,我们可以用数组来存储,也可以用链表来存储,回忆一下最短路径算法的两个做法。ps.,二维数组、三维数组也是一个连续存储的结构,在c语言debug下,看看地址就知道了。那么,不连续的存储结构,也就是链表,当然有很多的衍生:双向链表、十字链表、等等。 
16、显然,不管现实世界中的数据之间的关系如何,我们都可以用graph来描述,只不过是,不同的数据关系有不同的结构而已,比如:树、森林、mesh,等等。 
17、当然,我们要掌握一些常见的graph的操作方法,最主要就是搜索方法。而且还要注意,这些方法是分两个层次的,一个物理存储结构这个层次,一个是逻辑存储结构这个层次的。那么现在,深度优先搜索、广度优先搜索是哪个层次呢? 
18、当然,我们还要掌握一下存储结构的压缩。 
19、到了这个时候,我们还要问一下,各种方案的优劣性质如何,也就是空间复杂度和时间复杂度了。 
20、当然,我们这个时候,还要进一步的问一问,能不能将这些逻辑结构给出一个统一的描述,那么,就是抽象数据了。 
21、当然,我们还要掌握逻辑存储结构的各种树的优化,特别是针对不同的应用,比如红黑树、B树。 
22、当然,我们最后还要学习一下外存的存储结构。 
23、当然,实验是少不了的。自己debug一下内存单元的地址,并且在纸上手工的画一下是最好了。

原文地址:https://www.cnblogs.com/langjiaxing/p/8416628.html

时间: 2024-10-13 02:57:43

数据结构的本质的相关文章

基本数据结构和算法回顾

最近想回过头来看看以前写的一些代码,可叹为何刚进大学的时候不知道要养成写博客的好习惯.现在好多东西都没有做记录,后面也没再遇到相同的问题,忘的都差不多了.只能勉强整理了下面写的一些代码,这些代码有的有参考别人的代码,但都是自己曾经一点点敲的,挂出来,虽然很基础,但希望能对别人有帮助. 链表 链表是一种非常基本的数据结构,被广泛的用在各种语言的集合框架中. 首先链表是一张表,只不过链表中的元素在内存中不一定相邻,并且每个元素都可带有指向另一个元素的指针. 链表有,单项链表,双向链表,循环链表等.

【数据结构】java中LinkedList学习总结

一.LinkedList实现原理概述 LinkedList 和 ArrayList 一样,都实现了 List 接口,但其内部的数据结构有本质的不同.LinkedList 是基于链表实现的(通过名字也能区分开来),所以它的插入和删除操作比 ArrayList 更加高效.但也是由于其为基于链表的,所以随机访问的效率要比 ArrayList 差. 二.LinkedList类定义 public class LinkedList<E> extends AbstractSequentialList<

浅谈数据结构系列 栈和队列

计算机程序离不开算法和数据结构,在数据结构算法应用中,栈和队列应用你比较广泛,因为两者在数据存放和读取方面效率比较高,本章节重点讲解两者的基本概念和实现. 基本概念 栈:是一种先进后出,后进先出的数据结构,本质上是线性表,只是限制仅允许在表的一段进行插入和删除工作.此端为栈顶,这是在栈中应用很关键的概念.所有数据的处理都是在栈顶进行的,进栈时,栈中元素增加,栈顶上移一位,出栈时栈顶下移一位.应用中比如:洗碗,每次洗干净的碗放在上面-进栈,取碗,从顶上取出一个-出栈:装子弹-进栈,开枪-出栈. 队

数据结构与算法分析(六)——算法设计技巧

从算法的实现向算法的设计转变,提供解决问题的思路 1.贪心算法 一种局部最优算法设计思路,思想是保证每一步选择在当前达到最优.一个很常见的贪心算法案例是零钱找取问题. 调度问题:书上的调度问题比较简单,其目标是所有作业的平均持续时间(调度+运行)最短,无论是但处理器还是多处理器,最优解的方案总是按作业的长短排序进行调度.<计算机算法设计与分析>上的作业调度的目标是最后完成时间最小,这要稍微复杂一些. 霍夫曼编码:最优编码必定保持满树的性质,基本问题在于找到总之最小的满二叉树.最简单的霍夫曼编码

数据结构---Set和Map

1.Set数据结构 Set本质上是一个没有重复数据的一种集合.Set本身也是一种数据结构的构造函数. 1.Set的初始化 var obj = new Set(参数): 上面生成一个Set的实例,obj是集合对象. 参数可以是数组,也可以是类数组(具有iterator接口的数据,如字符串) var obj = [...new Set([1,3,3,3])]; // [1,3] var obj = [...new Set('hellohello')]; // ['h','e','l','o'].jo

解析spark RDD

RDD是spark抽象的基石,可以说整个spark编程就是对RDD进行的操作 RDD是弹性的分布式数据集,它是只读的,可分区的,这个数据集的全部或者部分数据可以缓存在内存中,在多次计算间重用.所谓的弹性意思是:内存不够时可以与磁盘进行交换.这是RDD另一个特性:内存计算.就是将数据保存到内存中,同时为了解决内存容量大小的问题,他允许所有的数据我们可以自由的设置cache,和 是否cache RDD的特征: (1)有一个分片列表,就是这个RDD可以被切分,和hadoop一样,能被切分的数据才能并行

知其所以然(以算法学习为例)

原文发表于2008年 其实下文的绝大部分内容对所有学习都是同理的.只不过最近在正儿巴经地学算法,而后者又不是好啃的骨头,所以平时思考总结得就自然要比学其它东西要多一些. 问题:目前几乎所有的算法书的讲解方式都是欧几里德式的.瀑布式的.自上而下的.每一个推导步骤都是精准制导直接面向目标的.由因到果,定义.引理.定理.证明一样不少,井井有条一丝不乱毫无赘肉.而实际上,这完全把人类大脑创造发明的步骤给反过来了.看起来是阳关大道,实际上车马不通. 而对读者来说,这就等于直接告诉你答案&做法了,然后让你去

javascript-引用类型--Object类型

引用类型是一种数据结构,本质是数据和功能的集合.引用类型有时也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法.引用类型相当于java里面的类,javascript虽然是一门面向对象语言,但是它不支持传统面向对象语言的类和接口. 对象是某个特定引用类型的实例,对象可以通过new操作符后跟一个要创建的对象类型的名称来创建.例如: var o = new Object(); 这行代码创建了Object引用类型的一个新实例,然后将该实例保存在变量o中.它只为新对象定义了默认的属性和方法,仅仅

Spark学习之RDD的理解

转自:http://www.infoq.com/cn/articles/spark-core-rdd/ 感谢张逸老师的无私分享 RDD,全称为Resilient Distributed Datasets,是一个容错的.并行的数据结构,可以让用户显式地将数据存储到磁盘和内存中,并能控制数据的分区.同时,RDD还提供了一组丰富的操作来操作这些数据.在这些操作中,诸如map.flatMap.filter等转换操作实现了monad模式,很好地契合了Scala的集合操作.除此之外,RDD还提供了诸如joi