赞
踩
数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
数据结构分为两种:数据的逻辑结构和存储结构
逻辑结构根据数据元素之间存在的关系来划分,数据元素存在一对一关系则为线性结构(线性表),存在一对多或者多对多关系则为非线性结构(树结构、图结构、集合结构)
线性表:线性表、栈与队列(数据操作只能从一端或者两端进行)、字符串(数据元素仅有一个字符构成)、数组和广义表(?)。
树结构:树(具有多个分支的层次结构)和二叉树(具有两个分支的层次结构)。
图结构:有向图(边有方向,具体表现在数据结构存储上是用顶点的有序对表示边)和无向图(边是顶点的无序对)
存储结构是数据对象在计算机中的存储表示。分为两类:顺序存储结构和链式存储结构。
顺序存储结构利用元素在存储器中的相对位置来表示数据元素之间的逻辑关系。典型的顺序存储结构是数组。要求所有的元素存放在一篇连续的存储空间中。
链式存储结构利用元素在计算机中的绝对位置来表示数据元素之间的逻辑关系。因此需要给每个节点附加指针字段,用于存放后续元素的存储地址。常用指针类型来描述。
算法是为了解决某类问题而定义的一个有限长的操作序列。
算法的特性:有穷性、确定性、可行性、输入、输出。
评价算法的标准:正确性、可读性、健壮性、高效性。
*O(n)的大O是什么意思?什么是时间复杂度? ★★★
O(n)这个大O表示的是最坏情况下的时间复杂度,时间复杂度是指执行算法所需要的计算工作量,对程序规模得一个描述。
线性表:由n个数据特性相同的元素构成的有限序列。
线性表作为线性数据结构当中的重要部分,栈和数组、字符串、数组和广义表都是特殊的线性表,因此本章主要从存储结构的出发点来看线性表,也就是说分为线性表的顺序存储表示和链式存储表示。
线性表的顺序表示指的是线性表当中的数据元素通过一段地址连续的存储单元进行存储。因此特点便是逻辑上相邻的元素,在物理结构上也是相邻的。是一种随机存取的存储结构。
操作(增删改查):
注意增加删除,均需要在要求位置增加(或者删除)元素之后,将后续元素后退(或者前进)一位。
线性表的链式表示指的是线性表通过包含的两个域(数据域和指针域)来关联各个数据元素从而进行存储
*头指针和头结点的区别?★★
以单链表为例,头指针表示指向第一个节点的 指针,若链表设有头节点,则头指针指向头节点,若链表没有设置头节点,则头指针指向首元节点(是链表中第一个存储数据元素的节点)。
头节点是在首元节点之前设置的一个节点,其指针域指向首元节点,数据域可以存放也可以不存放链表的相关信息,在一个链表中至少存在一个头节点,为的是方便链表的增删,若链表为空表时,增加一个节点或再非空表第一个节点之前插入一个节点时使用通用方法不需要对链表进行特殊判断。
*线性存储结构和链式存储结构的优点★★★
1、空间上看
存储空间分配:顺序存储结构需要一整块连续的区域进行存储,链式表则不需要,因此顺序表必须预先分配,在元素扩充的时候受一定的限制,易造成空间的浪费或者空间溢出。而链式表则没有这个问题。
存储密度来看:顺序表不需要指针来连接元素空间,所以顺序表存储密度比链式表要高,存储空间利用率高。
2、时间性能上看
存取元素的效率:因为顺序存储结构支持随机存取,存取元素的时间复杂度位O(1),存取效率高,而链式表存取元素的时候要从元素链表的某个位置遍历所有链表,直到找到第i个位置上的元素为止,所以算法的时间复杂度位O(n),效率低。
增加删除元素的效率:对链表,确认增加删除元素的位置之后,只需要修改指针即可,算法时间复杂度低,效率高,而顺序表则需要对之后元素进行移位操作,效率低。
栈是限定只在表尾(即栈顶)进行新增或删除操作的线性表。
队列是一种先进先出的线性表,在队尾进行插入,队头进行删除。
判断栈空和栈满:栈顶指针指向栈底指针表示栈空,栈顶指针减去栈底指针为栈允许容纳的最大值。
判断循环队列空和队列满: 队头指针等于队尾指针表示队列空,队尾指针加上一对队列最大容纳空间进行取余操作,若等于队头指针则代表队列满
对于循环队列来说,判断时少用一个元素空间,当有n-1个元素的时候则代表循环队列满了。
字符串最终要的就是字符串匹配算法,即KMP算法:
介绍一下字符串匹配算法:朴素的匹配算法和KMP算法。(如何实现要会用语言描述)★★★
树是n个节点的有限集,它或为空树,当树不空时,对于非空树:
1、树的节点有且仅有一个。
2、根节点的每个节点均是一棵树。除根节点意外各个节点分别分成互不相交的子集T1、T2、T3.....(分成互不相交的两个子集即为二叉树)。
节点的度:节点拥有的子树的个数称为节点的度。树的度:代表树内节点度的最大值。
*如何由遍历序列构造一颗二叉树?/已知先序序列和后序序列能否重现二叉树?(笔试经常考)★★★
树的前序和中序或者中序和后序均可得到另外一个顺序的遍历。
具体方法:可以通过前序和后序确定根节点,再根据中序确定左子树和右子树,然后递归确定左子树和右子树的根节点,当左子树和右子树为空时返回。
有三个性质:
性质1:在二叉树第i层上至多右2^(i-1)个节点。
性质2:对于深度为i的二叉树至多右2^(i)-1个节点。
性质3:对于任一颗二叉树,其度数为0的节点永远比度数为2的节点大1。
满二叉树:二叉树上每一个节点的左右子树均同时存在或为空,即每一层的节点树都是最大的节点数,为2^(i-1)。
完全二叉树定义:n个节点的完全二叉树的编号和它深度相同的满二叉树的前n个节点的位置一一对应。
二叉排序树和二叉搜索树:二叉排序树(二叉搜索树)的任意节点的左孩子的值一定小于该节点,右节点的值一定大于该节点。构造方法:对于该树的构造主要执行插入操作,搜索该节点在树中是否存在,若存在则不执行任何操作,若不存在则在搜索停止的地方插入新元素。
平衡二叉树:定义需要满足两个条件:1、是二叉排序树2、左子树的高度与右子树的高度差值不大于一。构造方式:通过插入的方式构造平衡二叉树,在插入的时候计算每个节点的平衡因子,即左子树与右子树的差值,若大于一则需要进行旋转操作来矫正。
哈夫曼树的定义:哈夫曼树是根节点到任意节点的路径是所能构造的树里面带权路径长度最短的树。
构造方式:从节点中选出权值最小的两个节点挑出,将两个节点的和加入树中,并将新节点记录其左右孩子,重复上述步骤,直至节点序列中只有一个根节点为止。
1、邻接矩阵表示法:
若图有n个节点,则创建一个n*n的矩阵,矩阵对应i行j列即第i个节点到第j个节点是否导通或者路径权重是多少。
2、邻接表表示法
邻接表是图的链式存储结构,创建一个n个节点的图之前,首先创建一个n个元素的数组,每个元素对应图的一个节点,每个数组元素后面链接所有与之导通的节点编号。
邻接矩阵适合存储稠密图,而邻接表适合存储稀疏图。
首先我用邻接表的方式存储图或这树的节点。
对于深度优先搜索来说,首先访问初始节点,然后递归遍历该节点的所有子节点,直至遇到一个没有未访问过的子节点的节点,则回溯到上一个节点。重复这一步骤直至所有节点均被访问过一遍为止。
对于广度优先搜索来说,分层遍历所有节点,首先从起始节点开始,访问该起始节点的所有相邻节点,访问结束后,再访问其相邻节点相邻的所有节点,层层类推,直至所有节点被访问完成。我利用队列来存储待访问的节点,首先将起始节点入队,在将其所有相邻节点依次入队后,弹出起始节点表示访问完成,再将下一个出队的节点的所有相邻的未被访问的节点入队,入队完成后在上述节点弹出。以此类推直至当队列为空,表示访问完所有节点。
图有四个应用:最小生成树、最短路径、拓扑排序和关键路径四种应用。
最小生成树是用来解决用最短的建设路径来使n个节点联通。
可以用prim算法和kruskal算法来实现。
prim算法:
首先将初始节点u加入集合U中,对于其他节点,用一个close数组来初始化其余节点到集合U的最短边信息,即现在为其他节点到u的最短边。
循环n-1次:选取最短的一条边,并将其对应的除了已存在集合U之外的一个点记为k加入到集合U中,然后用此节点更新close数组,即除在集合U中的所有节点,如果新边的权值比close数组的小,则将close数组中对应更新为新边的值。
kruskal算法:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。