数据结构学习笔记1-入门
定义
数据结构,直白地理解,就是研究数据的存储方式。
例如,一直以来大家面对的数据存储解决方式无疑是用变量或者数组对数据进行存储,即:
int a=1;
int b=2;
char str[3]={'a','b','c'};
char *data="http://data.biancheng.net";
但是,如果要存储这样一组数据:{张亮,张平,张华,张群,张晶,张磊},数据之间具有这样的关系:张亮是张平、张华和张群的父亲,同时张平还是张晶和张磊的父亲,数据之间的关系如图 1 所示:
对于存储之间具有复杂关系的数据,如果还是用变量或数组来存储(比如用数组存储 {“张亮”,“张平”,“张华”,“张群”,“张晶”,“张磊”} ),数据存储是没有问题,但是无法体现数据之间的逻辑关系,后期根本无法使用,显然不明智。
针对此类数据,数据结构中提供有专门的树结构来存储这类数据。
再比如,导航无疑是出游旅行的必备神器,在我们程序员眼中,无论是哪款导航软件,其导航功能的实现都需要大量地图数据的支持。很明显,这些数据绝不是使用变量或数组进行存储的,那样对于数据的使用简直是个悲剧。
针对此类数据,数据结构提供了图存储结构,专门用于存储这类数据。
数据结构是一门学科,它教会我们“如何存储具有复杂关系的数据更有助于后期对数据的再利用”。
内容
- 线性表
- 树结构
- 图结构
线性表
】
线性表并不是一种具体的存储结构,它包含顺序存储结构和链式存储结构,是顺序表和链表的统称。
顺序表
链表
栈和队列
栈和队列隶属于线性表,是特殊的线性表,因为它们对线性表中元素的进出做了明确的要求。
栈中的元素只能从线性表的一端进出(另一端封死),且要遵循“先入后出”的原则,即先进栈的元素后出栈。
队列中的元素只能从线性表的一端进,从另一端出,且要遵循“先入先出”的特点,即先进队列的元素也要先出队列。
树
图
条件
数学基础不是学习数据结构的必备条件,但好的数据基础对学习数据结构大有助益。
理解能力
专注能力
物理结构
数据存储结构的选择取决于两方面,即数据的逻辑结构和存储结构(又称物理结构)。
逻辑结构
数据的逻辑结构,简单地理解,就是指的数据之间的逻辑关系。
图 1 家庭成员关系图
图 2 “多对多”关系示意图
数据之间的逻辑关系可细分为三类,“一对一”、“一对多”和“多对多”:
“一对一”:类似集合 {1,2,3,…,n} 这类的数据,每个数据的左侧有且仅有一个数据与其相邻(除 1 外);同样,每个数据的右侧也只有一个数据与其相邻(除 n 外),所有的数据都是如此,就说数据之间是“一对一”的逻辑关系;
“一对多”:图 1 中的数据就属于“一对多”,因为对于张平来说,有且仅有一个父亲(张亮),但是有 2(多)个孩子;
“多对多”:拿图 2 来说,从 V1 可以到达 V2、V3、V4,同样,从 V2、V3、V4 也可以到达 V1,对于V1、V2、V3和V4来说,它们之间就是“多对多”的关系;
通过学习数据结构,我们可以学到 3 种存储结构分别存储这 3 类逻辑关系的数据,换句话说:
线性表用于存储具有“一对一”逻辑关系的数据;
树结构用于存储具有“一对多”关系的数据;
图结构用于存储具有“多对多”关系的数据;
存储结构(物理结构)
数据的存储结构,也就是物理结构,指的是数据在物理存储空间上选择集中存放还是分散存放。
图 3 数据的物理存储方式
将数据进行集中存储有利于后期对数据进行遍历操作,而分散存储更有利于后期增加或删除数据。因此,如果后期需要对数据进行大量的检索(遍历),就选择集中存储;反之,若后期需要对数据做进一步更新(增加或删除),则选择分散存储。
算法
算法的好坏
解决问题的算法有多种,我们就需要从中选出最好的那一个
每一位初学者都要掌握一个技能,即善于运用时间复杂度和空间复杂度来衡量一个算法的运行效率。
时间复杂度
根据算法编写出的程序,运行时间更短,运行期间占用的内存更少,该算法的运行效率就更高,算法也就更好。
关系
数据结构和算法之间完全是两个相互独立的学科,如果非说它们有关系,那也只是互利共赢、“1+1>2”的关系。
数据结构用于解决数据存储问题,而算法是思考如何利用存储的数据快速无误地解决问题,它们是完全不同的两类学科。
学习数据结构和算法有一个很重要的前提,就是至少熟练掌握一门编程语言。
可以总结为 6 个字:多动笔、多动手。
所谓“多动笔”,在学习数据结构和算法的过程中,要边学习边画图。因为,对于数据结构中的存储结构来说,尤其是树结构和图结构,存储结构确实比较复杂,仅靠空间想象难免会有纰漏,而通过亲手画图往往能避免很多“坑”。
以学习链表(后续章节会做详细讲解)为例,如果我们想象不到它是怎样存储数据,就应该尝试动手将它画出来,如图 1 所示:
由此,我们就画了一个存有 {1,2,3,4} 数据的链表。
不仅如此,假设在图 1 的基础上想删除存储元素 3 的结点,也可以先通过画图来实现:
在通过“多动手”实现理解存储结构和实现逻辑的基础上,初学者还要“多动手”编写实现代码。注意,对于某一种存储结构或者算法,没有 3 遍以上自己独立的实现过程,是很难做到融会贯通的。
总之,数据结构确实是一门比较难理解的学科,而且学习过程没有任何捷径可走。这意味着,想要学好数据结构,除了找一套适合自己的学习资料和学习方法外,更要有一种“死磕”的精神,有句话说的很好,“不逼自己一把,永远不知道自己有多大的潜力”。
作用
毋庸置疑,数据结构不仅有用,更应该是每个程序员必须掌握的基本功。
提升程序员的逻辑思维
掌握了数据结构与算法,我们看待问题的深度、解决问题的角度会大有不同,对于个人逻辑思维的提升,也是质的飞跃。
能力高低的分水岭
IT 公司都特别注重对数据结构的考察
程序性能好坏的评判标准
总结
有些知识并非学习了就能立竿见影,但学懂它会让你有整体的提升,数据结构就是这样的知识。