1、绪论
-
数据结构
数据结构是相互之间存在一种或多种特定关系的数据元素的集合,根据数据元素之间关系的不同特性,数据结构包括三方面的内容:逻辑结构、存储结构、数据的运算
-
逻辑结构
数据元素之间的逻辑关系,与数据的存储无关,独立于计算机。分为线性结构(线性表)与非线性结构(集合、树、图)。四类基本数据结构是指数据元素之间的逻辑关系:线性结构,集合结构,树形结构,图形结构(网状结构)
-
存储结构
数据结构在计算机中的映像(表示),包括数据元素的表示和关系的表示。存储结构主要有顺序存储、链式存储、索引存储、散列存储- 顺序存储:逻辑上相邻的元素物理位置存储单元也相邻,元素关系由存储单元的邻接关系表示。优点:随机存取,缺点:需要相邻一整块存储单元,可能产生较多存储碎片。
- 链式存储:不要求逻辑上相邻的元素物理位置存储单元也相邻,元素关系由元素存储地址的指针表示,优点:充分利用存储空间。缺点:存储指针需要额外存储空间,只能顺序存取。
- 索引存储:在存储元素信息的同时还建立附加的索引表。索引表中的每项称为索引项,索引项的一般形式是(关键字,地址)。优点是检索速度快,缺点是索引表需要额外存储空间。
- 散列存储:根据元素的关键字直接计算出该元素的存储地址,又称哈希存储。缺点与散列函数优劣有关,可能造成存储单元冲突。
-
顺序存储结构的特点?(顺序存储和链式存储的优缺点)
- 静态结构、存储密度大,空间利用率低(缺点)
- 结点中只存放数据元素本身的信息。(优点)
- 可直接存储数据元素,存储速度快。(优点)
- 插入、删除数据元素会引起节点大量移动。(缺点)
-
链式存储结构的特点?(顺序存储和链式存储的优缺点)
- 动态存储结构,存储密度小,空间利用率高。
- 结点中除存放数据元素本身的信息外,还需存放附加的指针。
- 不能直接存取数据元素,需顺链查找,存取速度较慢。
- 插入、删除元素速度快。(优点)
-
数据
是描述客观事物属性的数、字符及能输入到计算机中并被识别和处理的符号集合。 -
数据元素
数据的基本单元,一个数据元素由若干个数据项组成 -
数据项
构成数据元素不可分割的最小单位,一个数据元素由若干个数据项组成 -
数据对象
具有相同性质的数据元素的集合,是数据的一个子集。 -
数据类型
是一个值的集合和定义在此集合上的一组操作数的总称,分为原子类型(不可再分),结构类型(可再分为若干数据类型),抽象数据结构(抽象数据组织与之相关的操作)。 -
算法
对特定问题求解步骤的一种描述,是指令的有限序列。算法的五个特性:可行性、确定性、有穷性、输入和输出。
算法设计的要求:正确性、可读性、稳健性、高效率低存储量。
-
沃斯公式:程序=算法+数据结构。
-
(算法分析)衡量算法的两个标准:时间复杂度和空间复杂度。
一个算法的设计取决于所选的逻辑结构。
一个算法的实现取决于所选的存储结构。 -
时间复杂度
时间复杂度是指算法执行时间与问题规模之间的关系,用大O符号表示,记为T (n) = O(f (n)),其中n是问题规模,f (n)是一个函数,表示算法执行时间随n的增长而增长的量级。- 对数阶O(log n),表示算法执行时间与问题规模的对数成正比,如二分查找或折半插入排序。
- 线性阶O(n),表示算法执行时间与问题规模成正比,如顺序查找或冒泡排序。
- 线性对数阶O(n log n),表示算法执行时间与问题规模和问题规模的对数的乘积成正比,如快速排序或归并排序。
- 平方阶O(n^2),表示算法执行时间与问题规模的平方成正比,如选择排序或插入排序。
-
空间复杂度
指算法在执行过程中所占用的存储空间与问题规模之间的关系,用大O符号表示,记为S (n) = O(f (n)),其中n是问题规模,f (n)是一个函数,表示算法占用空间随n的增长而增长的量级。- 线性阶O(n),表示算法占用空间与问题规模成正比,如动态数组或链表。
- 平方阶O(n^2),表示算法占用空间与问题规模的平方成正比,如二维数组或矩阵。
-
结构化程序设计思想
自顶而下:程序设计时,应先考虑总体,后考虑细节。
逐步细化:对复杂问题,应设计一些子目标作为过渡,逐步细化。
结构化编码
模块化设计:模块化是把程序要解决的总目标分解为子目标,再进一步分解为具体的小目标,把每一个小目标称为一个模块。
-
存储密度
存储密度=(结点数据本身所占的存储量)/(结点结构所占的存储总量)
-
数据结构与数据类型的区别和联系?
数据结构是相互之间存在一种或多种特定关系的数据元素的集合,是计算机存储和数据组织的方式,它分为三个方面,即数据的逻辑结构,数据的物理结构,数据的操作,它偏向于逻辑方面。
数据类型是一个值的集合以及定义在这个值上的一组操作,可分为原子类型和结构类型,它偏向于物理方面的线性表。
2、线性表
-
线性表:具有相同数据类型数据元素的有限序列。除首尾元素外,每个元素有唯一的前驱和唯一的后继。
-
线性结构的特点:除首尾元素外,每个元素有唯一的前驱和唯一的后继,第一个元素没有前驱,最后一个元素没有后继,关系是一对一的。
-
非线性结构的特点是:表示结点间关系的前驱后继不具有唯一性,结点间是一对多或多对多的关系。
-
顺序表:采用顺序存储结构的线性表通常称为顺序表。
-
链表:采用链式存储结构的线性表通常称为顺序表。
-
结点:由数据元素和指示其后继结点地址的信息组成的存储映像称为结点。
-
循环链表:表中最后一个结点的指针域指向头结点,形成一个环,所构成的一种链表。
-
双链表:表每个结点除一个数据域外,还有两个指针域,其一指向直接前驱,另一指向直接后继,所构成的一种链表。
-
静态单链表:一块连续的空间,按链表的存储方式组织数据,按顺序存储结构分配空间,所构成的一种链表。
-
头指针:指向链表表头结点的指针,只要链表存在,该指针始终不会改变,单链表由头指针唯一确定。
-
头结点:在链表的开始结点之前附加的一个结点,是链表的表头。当链表不空时,其内的指针指向链表的第一个结点,当链表是空链表时,该指针为空指针。
-
填空题:
线性表的两种基本的存储结构:顺序结构和链式存储结构。
从实现角度看,链表可分为静态链表和动态链表。
从链接方式的角度看,链表可以分为单链表,双链表,循环链表。
添加哨兵可以保持首指针的稳定性,方便表示空表。
一元多项式的表示和相加可以使用链表实现。
-
简答题:
-
顺序表和链表的区别和联系及适用范围?
顺序表:内存中地址连续
长度一般不可变更
支持随机查找,可在O(1)内查找元素
适用于需要大量访问元素的,而少量増删元素的程序链表: 内存中地址连续或非连续都可以
长度可实时变化
不支持随机查找,查找元素的时间复杂度为O(n)
适用于需要大量增删元素,而对访问元素几乎无要求的程序 -
头指针和头结点的作用?
头指针:指向链表表头结点的指针,只要链表存在,该指针始终不会改变,单链表由头指针唯一确定。
头结点:在链表的开始结点之前附加的一个结点,是链表的表头。当链表不空时,其内的指针指向链表的第一个结点,当链表是空链表时,该指针为空指针。
-
简述在单循环链表上尾指针取代头指针的作用?
在用头指针表示的单循环链表中,找开始结点a1的时间是O(1),然而要找终端结点an则需要从头指针开始遍历整个链表,其时间是O(n),如果改用尾指针来表示单循环链表,则查找开始结点a1和终端结点an都很方便查找时间都是O(1)
-
3、栈和队列
-
栈:后进先出表,限定仅在表尾进行插入和删除操作的线性表,表尾端称为栈顶,表头端称为栈底
- 栈满的判断条件:top= n
- 栈空的判断条件:top=0
- 栈的应用:程调用,保护现场,括号匹配
-
队列:先进先出表,在表的一端进行插入,而另一端删除元素,允许插入的一端叫做队尾,允许删除的一端称为队首
-
循环队列:先进先出表,将队列的数据区看成头尾相接的循环结构,可解决“假溢出”
- 队满条件:(rear+1)%n==front
- 队空条件:rear==front
- 队中元素个数:(rear-front+n)%n
-
堆栈用于子程调用和保护现场,队列用于多道作业处理,指令寄存及其他运算等
4、串
-
串:是由零个或多个字符組成的有限序列.
-
子串:串中任意个连续的字符组成的子序列称作该串的子串
-
主串:包含子串的串为主串
-
子串在主串中的位置:子串的第一个字符在主串中的位置表示
-
空串:长度为零的串称为空串
-
空格串:串中元素均为空格的串称为空格串.
-
串相等:长度相等且对应位置字符都相等
-
填空
- 在程序中,串分为串常量和串变量
- 串的存储结构:顺序存储结构,链式存储结构,堆存存储结构
- 串的应用:文本編辑
5、广义表
-
广义表:由零个或多个单元素或子表所构成的有限序列,是线性表的推广
-
数组:类型一致的有限个数据元素按顺序连续存储
-
矩阵的压缩存储:矩阵对多个值相同的元素只分配一个存储空间,零元素不存储的存储策略
-
特殊矩阵:值相同的元素或者零元素有一定分布规律的矩阵
-
稀疏矩阵:非零的数据元素个数很少的矩阵
-
对称矩阵:一个n阶方阵,若满足aij=aji,则称该矩阵为对称矩阵
-
三角矩阵:主对角线上方和下方的元素(不包括对角线)均为常数或零元素的矩阵
-
简答题
-
广义表和线性表的区别?
广义表是线性表的推广,是由零个或多个单元素或子表所构成的有限序列
线性表的成分都是结构上不可分制的单个数据元素,而广义表的成分既可以是单元素,也可以是有结构的表其定义是递归的定义
6、树和二叉树
-
树:是n个结点的有限集合,n≥0,有且只有一个无前驱的根结点
-
有序树:各子树看成是从左至右依次有序的,且不能交换
-
森林:m(m≥1)棵互不相交的树的集合
-
二叉树:每个结点之多有两棵子树的有序树
-
完全二叉树:深度为k的n个结点二叉树,节点编号与从1至n的结点一一对应
-
满二叉树:是一棵深度为k的,且有(2^k)-1个结点的二又树
-
线索二叉树:
- 由每个结点中包含左指针,左标志位,数据域,右标志位,右指针五部分组成的二叉链表,叫做线索链表,
- 指向前驱或后继的指针叫做线索,以二叉树某种遍历顺序给空指针加线索的过程叫做线索化,
- 线索化了的二叉树称为线索二叉树
-
哈夫曼树:又称最优二叉树,是一类带权路径长度最短的树.
-
哈夫曼编码:在哈夫曼树中,约定左分支代表0,右分支代表1,把叶子结点到根结点的路径上的左右分支代表的码从下至上一次连接起来,组成的字符串称为该叶子结点的哈夫曼编码,这就是哈夫曼编码
-
二叉排序树:或者是空树,或者是符合以下性质的二叉树
- 若它的左子树不空,则左子树上所有结点均小于它的根结点值
- 若它的右子树不空则右子树上所有结点均大于它的根结点值.
-
平衡二叉排序树(AVL树):或者是空树,或者是符合一下性质的二叉排序树
- 左子树和右子树的高度之差的绝对值小于等于1
- 左子树和右子树也是平衡二叉排序树
-
填空题
- n个结点的二叉链表含有n+1个空链域。
- 树的三种常用的存储方法:孩子表示法,双亲表示法和孩子兄弟表示法
- 树的遍历方法:先根遍历和后根遍历
- 树的总结点数=总分支数+1
- 度为m的树中第i层上最多m^(i-1)个结点
- 高度为h的m叉数至多有(m^h-1)/(m-1)个结点
- 具有n个结点的m叉树最小高度为【logm(n(m-1)+1)向上取整】
- 完全二叉树:叶子结点数=双分支节点数+1
- 二叉树:n总=n0+n1+n2
- 深度为h的二叉树中,(2^h)-1>=结点总数>2^(h-1)-1个,第k层最多2^(k-1)个结点
- 二叉树中,n0=n2+1,n2=n0-1(no为二叉树中度为0的结点的个数,n2为二叉树中度为2的结点的个数)
- 有n个结点的完全二叉树,深度为k,则k=[log2n]+1(log以2为底括号是向下取整不是方括号)
- k层的完全二叉树至少有2^k-2个叶子结点
- 二叉树的两种存储结构:顺序存储结构和链式存储结构
-
简答题
哈夫曼树特点:
- 权值越大距离根节点越近。
- 树的带权路径长度最短。
- 树中没有度为1的结点为严格二叉树。
7、图
- 图:记为G=(V,E),其中V是顶点的有穷非空集合,E是顶点的有序偶对
- 顶点:图中的数据元素称为顶点
- 完全图:无向图中任意两个顶点之间都有一条边相连,为完全图。n个顶点n(n-1)/2条边。
- 有向完全图:图中每个顶点和其余n-1个顶点都有弧相连,n个顶点有n(n-1)条边的有向图称为有向完全图
- 入度:以顶点V为弧头(含箭头的一端)的弧的数目称为V的入度
- 出度:以顶点V为弧尾的弧的数目称为V的出度
- 连通图:在无向图中,任意两个顶点之间都有路径相通
- 强连通图:在有向图中,任意两个顶点之间都有来回路径相通,极大强连通子图称为连通分量。
- 生成树:生成树是无向连通图的一个极小连通子图,它含有图中的全部顶点和使任意顶点都连通的最少的边
- 邻接矩阵:表示图中结点之间关系的矩阵称为邻接矩阵,是图的顺序存储结构。
- 邻接表:由顶点数据表和表示数据关系的边(弧)构成的表,是图的链式存储结构。
- 对于n个顶点的无向图G,若G是连通图,最少有n-1条边。若G是非连通图,最多(n-1)(n-2)/2条边
- 对于n个顶点的有向图G,若G是强联通图,则至少有n条边。
- 最小生成树:无向图中边上权值之和为最小的生成树
- DAG:有向无环网
- 拓扑排序:由某个集合上的一个偏序得到该集合上一个全序的操作称为拓扑排序
- 关键路径:在AOE网中,从源点到汇点的最大路径长度的路径称为关键路径
- AOE网:用顶点表示事件,用弧表示活动,弧的权值表示活动所需的时间,构造的有向网称为AOE网
- 简单路径:一条路径上除了开始顶点和结束顶点外,其余顶点均不相同
填空题:
边很少的图称为稀疏图,反之称为稠密图
有向图中,所有顶点的入度与出度的和等于边个数的2倍
图的深度优先搜索类似于树的先根遍历
图的广度优先搜索类似于树的层次遍历
简答题
-
邻接矩阵表示法的特点?
1.对于无向图而言,它的邻接矩阵是对称矩阵,因此可以采用特殊矩阵的压缩存储法,但对于有向图而言,其中的弧是有方向的,因此有向图的邻接矩阵不一定是对称矩阵,对于有向图的邻接矩阵的存储则需要n*n个存储空间.
2.采用邻接矩阵表示法,便于判断图中任意两个顶点之间是否有边相连,即根据邻接矩阵中的信息来判断,另外还便于求得各个顶点的度,对于无向图而言,其邻接矩阵第i行元素之和就是图中第i个顶点的度
-
邻接表表示法的特点?
1.n个顶点,e条边的无向图,若采取邻接表作为存储结构,需要n个顶点数据和2e个表示边的结点,显然在边很稀疏的情况下,用邻接表存储所需的空间比邻接矩阵所需的空间少
2.无向图的度,在无向图的邻接表中,顶点Vi的度恰好就是第i个边链表上结点的
3.有向图的度,在有向图中,第i个边链表上结点的个数就是顶点Vi的出度,只需通过表头向量表中找到第i个顶点的边链表的头指针,实现顺链查找计数即可
-
DFS(深度优先搜索遍历)的基本思路?
假设初始状态是图中所有顶点均未被访问过,则深度优先搜索可从某个顶点V出发,首先访间此顶点(称此顶点为初始点),然后依次从V的任一个未被访问的邻接点出发进行深度优先搜索遍历,直到图中所有与有路径相通的顶点都被访问到,若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作为初始点,重复上述步骤,直到图中所有顶点都被访问过为止
-
BFS(广度优先搜索遍历)的基本思路?
1.从图中某个顶点VO出发,首先访问VO,依次访问Vo的各个未被访间的邻接点
2.分别从这些邻接点(端结点)出发,依次访问各个未被访问的邻接点,访问时应保证:如果Vi和Vk为当前结点,且Vi在Vk之前被访问,则Vi的所有未被访问的邻接点应在Vk的所有未被访问的邻接点之前访问
3.重复步骤2,直到所有结点均没有未被访问的邻接点
4.若此时还有顶点未被访问,则选一个未被访问的顶点作为起始点,重复上述过程,直至所有顶点均被访问过为止