8种基础数据结构
数据结构有8类:
1、数组: 数组是可以在内存中连续存储多个元素的结构,内存中分配也是连续的。通过下标访问,下标从0开始。
2、栈:栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。 先进后出(后进先出), 放入元素叫入栈,取出元素叫出栈。
3、队列:队列也是一种线性表,队列可以在一端添加元素,在另一端取出元素。先进先出。 放入元素叫入队,取出元素叫出队。
4、链表:链表是物理存储单元上非连续的,非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个节点,一个是存储元素的数据域(内存空间),另一个是指向下一个节点地址的指针域。 根据指针的指向,链表能够形成不同的结构,例如: 单链表、双向链表、循环链表等
5、树:树是由n(n>=1) 个悠闲节点组成一个具有层次关系的集合。 根据不同的特征,又分为: 红黑树、二叉树等
6、散列表(哈希表):散列表是根据关键码和值(key 和 value) 直接进行访问的数据结构,通过key和value来映射到集合中的一个位置,这样就可以很快找到集合中的对应元素
7、堆:堆是一种比较特殊的数据结构,可以被看做一棵树的数组对象,具有以下的性质:堆中某个节点的值总是不大于或不小于其父节点的值;堆总是一棵完全二叉树。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。
8、图:图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。
又可以分为: 线性结构 和 非线性结构
线性结构:特点是数据元素之间存在一对一的线性关系。 线性结构有两种不同的存储结构: 顺序存储结构(数组) 和 链式存储结构(链表)。
主要有 数组、队列、链表和栈。
非线性结构:主要有: 二维数组、多维数组、广义表、树结构、图结构
数据结构的细分类:
数组: 静态数组、动态数组。
静态数组: 已知内容长度
动态数组: 先定义长度,再进行赋值,可能需要扩展长度
链表: 单向链表、双向链表、循环链表
树:二叉树、查找树、平衡树、完全二叉树、线索树、线索树、堆
二叉树:二叉树特点是每个节点最多只能有两棵子树,且有左右之分。二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点。
二叉查找树(BST): 其中每一个节点都包含一个 Comparable 的键(以及其相关的值),且每个节点的键都大于其左子树中的任意节点的键而小于右子树的任意节点的键(即不允许重复)
平衡树(BT):任意节点的子树的高度差都小于等于1。 Balance Tree
B树:一颗多路平衡查找树。
特点:每个节点最多有 m-1 个关键字(可以存有键值对)
跟节点最少可以只有一个关键字
非跟节点至少有 m/2 个关键字
每个节点中的关键字都展昭从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树的所有关键字都大于它
所有叶子节点都位于同一层,或者说跟节点到每个叶子节点都长度都相同
每个节点都存有索引和数据,也就是对应的 key 和 value
B+树: 和B树非常相似
特点:(相同)跟节点最少有一个元素
(相同)非跟节点元素范围: m/2 <= k <= m-1
(不同)B+树有两种类型的节点:内部节点(也称索引节点)和叶子节点。内部节点就是非叶子节点,内部节点不存储数据,只存储索引,数据都存储在叶子节点。
(不同)内部节点中的key都按照从小到大的顺序排列,对于内部节点中的一个key, 左树中的所有key都小于它,右子树中的key都大于等于它。叶子结点中的记录也按照key的大小排列
(不同)每个叶子结点都存有相邻叶子结点的指针,叶子结点本身依关键字的大小自小而大顺序链接。
(不同)父节点存有右孩子的第一个元素的索引
红黑树:一棵自平衡二叉查找树
特点:节点不是黑色,就是红色(非黑即红)
根节点是黑色
叶节点为黑色(叶节点事指末梢的空节点 Nil 或 Null)
一个节点为红色,则其两个子节点必须是黑色的(根到叶子的所有路径,不可能存在两个连续的红色节点)
每个节点到叶子节点的所有路径,都包含相同数目的黑色节点(相同的黑色高度)
完全二叉树:一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
线索二叉树:在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。
堆:堆中某个结点的值总是不大于或不小于其父结点的值;堆总是一棵完全二叉树。
如何理解基础的数据结构:
各结构的优劣势及选择:
数组: 下标寻址十分迅速,但计算机的内存是有限的,故数组的长度也是有限的,实际应用当中的数据往往十分庞大;而且无序数组的查找最坏情况需要遍历整个数组;后来人们提出了二分查找,二分查找要求数组的构造一定有序,二分法查找解决了普通数组查找复杂度过高的问题。任何一种数组无法解决的问题就是插入、删除操作比较复杂,因此,在一个增删查改比较频繁的数据结构中,数组不会被优先考虑
普通链表:由于它的结构特点被证明根本不适合进行查找
哈希表:数组和链表的折中,同时它的设计依赖散列函数的设计,数组不能无限长、链表也不适合查找,所以也不适合大规模的查找
二叉查找树: 因为可能退化成链表,同样不适合进行查找
AVL树:是为了解决二叉查找树可能退化成链表问题。AVL树是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差的绝对值不超过1)。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入与删除次数比较少,但查找多的情况。
B*树:是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针, 在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3。
R树:是用来做空间数据存储的树状数据结构。例如给地理位置,矩形和多边形这类多维数据建立索引。
Trie树:是自然语言处理中最常用的数据结构,很多字符串处理任务都会用到。Trie树本身是一种有限状态自动机,还有很多变体。什么模式匹配、正则表达式,都与这有关
参考文档:https://www.pdai.tech/md/interview/x-interview.html#7-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95