数组(线性,随机访问)
特点:编译时分配存储空间,存储空间连续,可快速查找、修改指定下标的数据,但是插入、删除时需要移动指定下标之后的数据
字符串和数组:字符串就是一维数组+结束标志(空字符)
链表(线性,顺序访问)
特点:包含数据域和指针域,程序执行时分配存储空间,存储空间不连续(数据和存储位置无关),数据可伸缩、定向,可快速插入、删除数据、修改数据,但是查找比较慢(需要从第一个数据开始遍历)
1. 单向链表:只能检索下一个数据
结构:数据域:存储数据。指针域:next指针(指向下一个元素的指针)
2. 双向链表:检索上一个或下一个数据
结构:数据域:存储数据。指针域:next指针(指向下一个元素的指针),prev指针(指向上一个元素的指针)
3. 环形链表:链表尾部指针指向头部指针
HEAD指针:指向第一个元素的指针
TAIL指针:指向最后一个元素的指针
堆栈(线性)
特点:先进后出( FILO:first in last out ),所有操作都在堆栈的顶部(top)进行(每次只能访问最顶层的数据)
入栈(push):写入数据
出栈(pop):读取数据
队列(线性)
特点:先进先出( FIFO ),不能插队(添加数据在队尾,删除数据在队头,从队头第一个数据一个个往后处理)
入队(push):在队尾添加数据
出队(pop):返回队列前端的值
队列前端指针:front
队列尾端指针:rear
树
特点:由节点和边构成,起始点(根节点)不断分叉,不能形成没有出口的回路
父节点:节点连接的上一层
子节点:节点连接的下一层
叶子节点:没有节点的点
度数:节点所有的子节点个数
深度:树的最大层数
节点深度:由根节点出发,到达某个节点经过的边的个数
存储方式:一般是链表形式,对于n叉树,必须为每个节点保留n个指针存储空间
n叉树有m个节点,共用了nm个链接字段。除了树根,每个非空链接都指向一个节点,空节点的个数是nm-(m-1),
空节点的浪费率是(m*(n-1)+1)/(m*n)
二叉树
特点:每个节点最多有2个子节点,可以为空集合(树不可以),左子树的值小于树根值,右子树的值大于树根的值。每个节点的值一定大于其左子树的任意一个节点,一定大于右子树的任意一个节点。所有查找是从根节点开始,小于根节点往左边找,大于往右边。插入时也一样,直到往下没有节点时插入。删除时,如果没有子节点则直接删除;如果有一个子节点则把子节点移到该位置;如果有多个节点,则把左子树中的最大节点移动到该位置。
满二叉树:树的高度为h,数的节点为2^h-1
完全二叉树:树的高度为h,数的节点小于2^h-1,节点从左到右,从上到下。如果有n个节点,层数log2(n+1)
斜二叉树:完全没有左节点或右节点
严格二叉树:非终端节点一定有左右子树
用链表表示二叉树:一个数据,两个指针
用数组表示二叉树:根节点的索引是0,左节点索引=父节点索引2+1,右节点索引=父节点索引2+2
二叉树遍历:
中序遍历:左子树->树根->右子树(最底层、最左边的左子树开始->它的树根->右子树(如果它有子节点,则把右子树、右子树的子节点当做一个整体,按左子树->树根->右子树遍历),再往上)
前序遍历:树根->左子树->右子树
后序遍历:左子树->右子树->树根
二叉树查找:因为左子树<树根<右子树,所有从树根开始,小于树根往左,大于往右
二叉树插入:先查找再插入,如果节点已存在则不插入,否则找到插入位置(树的每个节点值都不同)
二叉树删除:只是删除这个节点,它的子节点不删除,如果只有一个子节点则放到它的位置上。如果有两个节点,有两种方法:
找出中序先行者:节点的左子树中最大的往上移
找出中序后继者:节点的右子树中最小的往上移
堆积树排序(改进选择排序)
最大堆积树:
1. 完全二叉树
2. 所有的节点都大于或等于它左右子节点的值
3. 树根是堆积树中最大的
最小堆积树:
1. 完全二叉树
2. 所有的节点都小于或等于它左右子节点的值
3. 树根是堆积树中最小的
图
特点:由顶点和边(2个顶点的连线)构成,G=(V,E),V是所有顶点的集合,E是所有边的集合
无向图:图的边没有方向,(v1,v2)表示边,与(v2,v1)等价
有向图:图的边有单向方向,<v1,v2>表示边v1指向v2
加权图:图的边有权重(连接程度),无权重的边只表示连接状态
遍历:从某一顶点开始,通过相邻顶点访问图中任意顶点
深度优先遍历:从图的某一顶点开始,访问没有访问过的顶点,被访问过的顶点做上标记(不再访问),以此顶点开始继续访问下一个
最小生成树(最小花费树):最少的边连通图中的所有顶点,且不造成回路
环形缓冲区
特点:一维数组收尾相连,每次都可以访问下一个数据
哈希表
特点:由key和value组成的存储数据的连续内存(键作为标识,值作为数据内容),通过哈希函数(计算出存储地址)可快速存取和查找数据。类似数据库的数据表的索引表格,可分为n个记录(桶),每个记录又分为m个字段(槽),由哈希函数计算的数据存储地址相当于主键id。
存储过程:把key通过哈希函数,得到哈希值(存储地址),把key和value放入该内存。如果该地址已经存有数据了,则再在已有数据后使用链表存储新的数据。查找时,通过key计算出存储地址,再找到对应的key,再获取值。
哈希法:将数据通过哈希函数转换为对应的数据存储地址
bucket桶:哈希表中存储数据的位置每个位置对应唯一的一个地(bucket adders),桶好比一个记录
slot槽:桶中的字段(一条记录可能好几个字段)
collision碰撞:两项不同的数据,经过哈希函数计算后,对应到相同的地址。解决方法:链地址法(使用链表)、开发地址法(计算出候补地址,再存储)
溢出:经过哈希函数运算后得到的地址(桶)已满,就会使桶溢出
同义词:两个标识符经过哈希函数运算后得到的数值相同,则这两个标识符对这个哈希函数是同义词。
完美哈希:没有碰撞也没有溢出的哈希函数
加载密度:标识符的使用数量除以哈希表内槽的总数