在看《算法(第4版)》这本书的过程中,作者将算法与数据结构结合进行讲解,阅读的过程中,意识到数据结构非常的重要。比如在第三章讲解查找算法时,适时的引入二叉树,高效的查找元素和避免了如线性表添加新元素需改变其他元素位置。高效的算法有赖于合理的数据结构,这本书给我很大影响之一是把数据结构和算法当为不可分离的整体来考虑,数据结构是一个好的算法的必要条件,所以先看的第一个概念是算法复杂度。
算法的时间复杂度和空间复杂度合称算法复杂度。
时间复杂度:可成为算法的渐进时间复杂度。T(n)= O(f(n))。表示随着问题规模 n 的增大,算法执行时间的增长率和 f ( n ) 的增长率相同。可理解为描述一个算法在问题规模不断增大时对应的时间增长曲线。算法的分析中,语句的总执行次数 T(n)是关于问题规模 n 的函数,算法花费的时间与算法中语句执行的次数是成正比的,语句频度 / 时间频度指一个算法中的语句执行次数,记为T(n)。f ( n ) 是问题规模 n 的某个函数。
大O表示法O(f(n))中的 f(n) 的值可为1、n、logn、n²等等,将 O(1)、O(n)、O(logn)、O(n²)分别称为常数阶、线性阶、对数阶、平方阶。
截取《算法(第4版)》中的关于增长数量级的一个图表来更好的理解:
空间复杂度:S(n)= O(f(n))。n 为问题的规模,f(n) 为语句关于 n 所占存储空间的函数。
逻辑结构:是指数据对象中数据元素之间的相互关系。
逻辑结构可分为四种:
1. 集合结构:集合结构中的数据元素处理同一个集合外,它们之间没有其他关系。
2. 线性结构:线性结构中的数据元素之间是一对一的关系。
3. 树形结构:树形结构中的数据元素之间存在一种一对多的层次关系。
4. 图形结构:图形结构的数据元素是多对多的关系。
物理结构:是指数据的逻辑结构在计算机中的存储形式。分为两种:
1. 顺序存储结构:吧数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。
2. 链式存储结构:把数据元素存放在任意的存储单元里,这组存储单元可是连续的,也可以是不连续的。
数据类型:是指一组性质相同的集合及定义在此集合上的一些操作的总称。
抽象数据类型(Abstract Data Type, ADT): 是指一个数学模型及定义在该模型上的一组操作。抽象数据类型体现了程序设计中问题分解、抽象和信息隐藏的特性。抽象是指抽取出事物具有的普遍性的本质。他是抽出问题的特征而忽略非本质的细节,是对具体事物的一个概括。
线性表:是由n >= 0个数据元素组成的有限序列。n=0是空表;非空表,只能有一个开始结点,有且只能有一个终端结点。
顺序表是按线性表的逻辑结构依次存放在一组地址连续的存储单元中。存储中的物理位置和逻辑结构中各结点相邻关系是一致的。
1.顺序存储:查找:时间复杂度为 O(1); 插入、删除 :算法复杂度为 O(n)。不需要为表中元素之间的逻辑关系而增加额外 的存储空间,可以快速的读取表中任一位置的元素,但是插入和删除需要移动大量元素,并且造成存储空间的碎片化。
2.单链表:查找、插入和删除结点的时间复杂度都是 O(n)。其中若是找到第 i 个位置的指针,插入和删除时间复杂度为 O(1)。若事先不知道线性表中的元素个数或变化较大,优先单链表结构,可不用考虑存储空间大小问题。
3.静态链表:可用数组代替指针描述链表:数组元素元素由data和cur组成,每个下标都对应一个data和cur,数据域data用来存放数据元素,cur则相当于单链表中的next指针,称为游标。这种用数组描述的链表为静态链表。
4.循环链表:单链表中终端结点的指针由空指针指向头结点,单链表则形成一个环,头尾相接的单链表称为单循环链表,即循环链表。与单链表的主要差异在于,判断循环的条件由 p->next是否为空到p->next不等于头结点。
5.双向链表:在单链表的每个结点中,再设置一个指向其前驱结点的指针域。
栈(Stack)是仅限在表的一端进行插入和删除运算的线性表:
1. 称插入、删除这一端为栈顶,另一端为栈底。
2. 后进先出。又称栈为LIFO表(Last In First Out)。
3. 可按存储结构分为:顺序栈;链栈。
3.“上溢”和“下溢”的现象。“上溢”指栈顶指针指出栈的外面,是出错状态。“下溢”表示栈为空栈。顺序栈有上溢限制,链栈没有上溢限制。
4. 顺序栈基本操作有六种:构造空栈;判栈空;判栈满;进栈;退栈;取栈顶元素。链栈没有判栈满,为五种操作。
队列(Queue)是一种运算受限的线性表:
1. 插入在一表的一端进行,而删除在表的另一端进行,允许删除的一端称为对头(front),允许插入的一端称为队尾(rear)。
2. 先进先出。称作FIFO表(First In First Out)。
3. 分为顺序存储结构和链式存储两种存储结构。
4. 循环队列:队列头尾相接的顺序存储结构。使得队头和队尾可以在数组中循环变化。解决了移动数据的时间损耗,使得本来插入和删除是O(n)的时间复杂度变为O(1)。
5. 链队列是一个操作受限的单链表。一个链队列由一个头指针和一个尾指针唯一的确定。
串(string):是零个或多个字符组成的有限序列。
1. 串的基本概念与规律:
空串:长度为零的串,串中无字符(结点)。
空白串:串中包含一个或多个空格字符的串。
一个串中任意个连续字符组成的子串称为该串的子串,包含子串的串称为主串。
子串在主串中的序号就是指子串在主串中首次出现的位置。
空串是任意串的子串,任意串是自身的子串。
2. 可分为顺序存储结构和链式存储结构。
串在本质上是一种线性表的扩展,但相对于线性表关注一个个元素来说,串更多关注子串的应用问题,eg:查找、替换等操作。
树 (Tree) 是 n (n>=0)个结点的有限集。n=0时称为空树。任意一颗非空树中:
1. 有且仅有一个特定的称为根 (Root)的结点;
2. 当 n > 1 时, 其余结点可分为 m (m>0)个互不相交的有限集T1、T2、...... 、Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。
结点分类:结点拥有的子树数称为结点的度(Degree)。度为0的结点称为叶结点(Leaf)或终端结点;度不为0的结点称为非终端结点或分支结点。
结点间关系:结点的子数的根称为该结点的孩子(Child),相应的,该结点称为孩子的Parent。同一个双亲的孩子之间互称兄弟
(Sibling)。以某结点为根的子树中的任一结点都称为该结点的子孙。
结点层次与树的深度:根为第一层,根的孩子为第二层,依次类推。双亲在同一层的结点互为堂兄弟。书中结点的最大层次称为树的深度(Depth)或高度。
森林(Forest)是 m (m>=0)颗互不相交的树的集合。
有序树与无序树:若树中结点的各子树从左至右是有次序的,不能互换为有序树。无序树反之。
线性表的数据之间是一对一,而树是一对多的结构,树的存储结构有三种:双亲表示法;孩子表示法;孩子兄弟表示法。
二叉树(Binary Tree):若非空二叉树,则由一个根结点和和两课互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
斜树:所有结点都只有左子树为左斜树,只有右子树为右斜树,两种统称为斜树。线性表即为树的一种特例。
满二叉树:所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上。
完全二叉树:一个有n个结点的二叉树按层序编号,如果编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。
满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树。
线索二叉树:指向前驱和猴急的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树。
线索化:对二叉树以某种次序遍历使其变为线索二叉树的过程。
霍夫曼编码:带权路径长度WPL最小的二叉树称作霍夫曼树。
图(Graph):由顶点的又穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。图中的数据元素称之为顶点(Vertex)。顶点之间的逻辑关系用边来表示。
无向边:若顶点 v1 到 v2 之间的边没有方向,称这条边为无向边(Edge),用无序偶对(Vi, Vj)表示。
有向边:若从顶点 Vi 到 Vj 的边有方向,则称这条边为有向边,也称为弧(Arc)。有序偶
有向图:图中任意两个顶点之间的边都是有向边,则称该图为有向图。
简单图:图中不存在顶点到其自身的边,且同一条边不重复出现。
无向完全图:无向图中,如果任意两个顶点之间都存在边,则称为无向完全图。
有向完全图:有向图中,如果任意两个顶点之间都存在方向互为相反的两条弧,则称为有向完全图。
稀疏图:有很少条边或弧的图,反之称为稠密图。
权(Weight):与图的边或弧相关的数叫做权。这些权可以表示从一个顶点到另一个顶点的距离或耗费。
网(Network): 带权的图通常称为网(Network)。
子图:假设有两个图G=(V,{ E }) 和 G' = (V', { E' }),如果V'是V的子集,且E'是E的子集,则称G'为G的子图。
TD(v)是顶点 v 的度,是和 v 相关联的边的数目。
路径(Path):无向图 G = (V, { E })中从顶点 v 到 v' 的路径是一个顶点序列(V = Vi,0,Vi,1, ... Vi,m = V')其中(Vi,j-1, Vi,j)∈ E , 1<= j <=m。路径的长度是路径上的边或弧的数目。
回路/环(Cycle): 第一个顶点到最后一个顶点相同的路径称为回路或环。序列中顶点不重复出现的路径为简单路径,除了第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路,称为简单回路或简单环。
连通图:在无向图G中,如果从顶点V到顶点V'有路径,称V和V'是连通的。如果对于图中任意两个顶点Vi, Vj ∈ E, 则G为连通图。
连通分量:无向图中的极大连通子图。
五种存储结构:邻接矩阵;邻接表;十字链表;邻接多重表;边集数组。
两种遍历次序方案:深度优先遍历;广度优先遍历。
最小生成树:把构造连通网的最小代价生成树称为最小生成树,两种经典算法为普里姆算法和克鲁斯卡尔算法。
最短路径:非网图边上没有权值,则指两顶点之间经过的边数最少的路径,网图的最短路径值两顶点之间经过的边上权值之和最少的路径,路径上的第一个顶点称为源点,最后一个顶点是终点。有迪杰斯特拉算法和弗洛伊德算法。
AOV网:一个表示工程的有向图中,用顶点表示活动,弧度表示活动之间的优先关系,这样的有向图为顶点表示活动的网。AOV网中不能存在回路。
拓扑排序:一个有向无环图的所有顶点的线性序列,需满足两个条件:1.每个顶点出现且只出现一次;2.若存在一条从顶点A到顶点B的路径,那么在序列中顶点A出现在顶点B的前面。
AOE网:在一个表示工程的带权有向图中,用顶点表示事件,有向边表示活动,用边上的权值表示活动的持续时间,这种有向图的边表示活动的网。
关键路径:路径上各个活动所持续的时间之和称为路径长度,从源点到汇点具有最大长度的路径叫关键路径,在关键路径上的活动称为关键活动。