数据结构——序

首先较常见的线性结构如下:

向量(vector):

与常见的数组极为相似,申请的是连续地址下的一段内存空间。不同点有很多,主要的点包括:作为一个类,接口的使用很方便,有很多较为使用的函数(包括排序、查找等),其占用的内存空间可以动态变化,当当前大小的内存空间被利用完后仍需要增加数据时会自动扩容(当然自动指的也是类里面定义的扩容函数)。向量的查找(search)操作效率很高为O(logn)的时间复杂度。用的排序方法为起泡排序和归并排序。

列表(LIST):

通过链表实现,与向量的区别在于其不要求数据的地址空间连续,而是通过记录前驱和后驱指针来保持数据的连续性,与向量结构相比,其优点在于对数据的插入和删除操作时O(1)的时间复杂度,而向量是O(n),缺点是其对于数据的查找工作是O(n)的时间复杂度,而向量是O(logn)。常用的排序方法为选择排序和插入排序。

堆栈(Stack):

LIFO(后入先出)结构,通过vector结构实现(这是因为只需要再栈顶进行数据的添加和删除,而vector结构的最后一个数据的插入和删除操作时间复杂度均为O(1),且对应的接口基本满足堆栈的要求)。

队列(queue):

FIFO(先入先出)结构,通过List结构实现(这是因为队列要在数据的头部尾部分别进行插入和删除操作,而List结构的插入和删除擦欧总均为O(1),且对应的接口基本满足队列的要求)。

上面提到的线性基础结构为vector和List都有其优缺点,但其都无法满足高查找效率和高插入删除效率的要求,即高效地兼顾静态操作和动态操作。

下面介绍树结构:

可以视为List<List>(列表的列表)结构,也可以看作是二维的列表,可以视为半线性结构,其更多的表示一种层次关系。

二叉树(二叉树-BinTree):

利用类似于链表的结构,不同的是每个二叉树节点-BinNode其带有的指针为一个父亲节点和两个孩子节点,其用于描述任意有根且有序的多叉树,其演绎的过程如下图。

 值得注意的是,在对二叉树遍历的时候有时需要用到其他数据结构,对于先序(根-左-右)、中序(左-根-右)、后序(左-右-根)遍历来说,其模式类似于DFS,因此再不采用递归调用的情况下需要使用堆栈结构;而对于层次遍历来说,其模式类似于BFS,因此其需要利用队列结构。

下面介绍图:

图(Graph):

图的基本构成即为点和边的集合G=(V;E),其中V即为点的集合(Vertex),E即为边的集合(Edge)。其表示形式一般分为两种,即邻接矩阵和邻接链表。

邻接矩阵,即通过构建N×N的数组来表示N个点之间的连接情况,1为连通,0为断开,显然对于无向图来说其邻接矩阵是对称的;值得注意的是,这里01对应的是无权图,当是有权图,其值可以代表边的权重。

邻接链表,即对每个顶点构建一个链表,其中包含其能够连通的点的集合。对于每个顶点来说,其链表空间大小应是不同的,即其所连边越多,其链表越大。

除上述外,还有一种表示方式为关联矩阵,但不太常用,不做过多了解。

对图的遍历方法一般包括深度优先搜索(DFS)和广度优先搜索(BFS),和两种方法再算法中常会被用到,这里也不多做介绍。值得注意的是在遍历的过程中记录下每个顶点的搜索时间和退出时间可以在之后很快的判断其是否在该遍历树中具有从属关系。例如顶点A的stime=1,dtime=10,而顶点B的stime=3,dtime=6,那么区间的包含说明B在A的搜索路径下被找到。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章