数据的逻辑结构:
(1)集合:任何两个元素之间没有逻辑
(2)线性结构:元素存在一对一的关系
(3)树形结构:数据元素存在一对多的关系
(4)图状结构:元素之间存在多对多的关系
数据的存储结构:
(1)顺序存储:存储于地址连续的存储单元
(2)链接存储:存储于任意的存储单元,用附加指针表示元素间逻辑关系
(3)索引存储:存储元素的同时建立附加的索引表
(4)散列存储:依据数据元素的关键字,用一个事先设计好的函数计算出该数据元素的存储地址。
一、线性表
定义:也称有序表,元素的有序集合。
类型:arrary、vector、list、forward_list
二、数组和矩阵
三、栈和队列
定义:
栈: 一种特殊的线性表,元素先进后出;
队列:一种特殊的线性表,元素先进先出;
类型:stack、queue
四、跳表和散列
定义:
跳表:有序链表加入额外的向前指针,平均时间复杂度O(logn)
散列:也称哈希,需要散列函数和散列表;
常用哈希函数:
求余散列函数 f(k) = k%D;
加法哈希函数;
位运算哈希函数
乘法哈希函数
查表哈希函数,CRC
哈希函数注意点:
单向算法,不可逆
抗碰撞性,避免冲突
抗篡改性,改动一个字节,哈希值差别够大
查找效率
哈希算法应用:
安全加密、数据校验、唯一标识、负载均衡、分布式缓存
五、树和二叉树
二叉树:
定义: 有限个元素的集合,当二叉树非空,其中一个元素为根,余下的元素被划为两棵二叉树,分别为根节点的左子树和右子树。
满二叉树:当高度为h的二叉树恰好有2^h - 1个元素。
完全二叉树:满二叉树从最后一层从右到左删除k个元素(1<= k < 2^h )个元素。
并查集:
优先级队列:
也称 大顶堆(小顶堆),是一棵完全二叉树,每个节点的值都大于(小于)或等于其子节点(如果有子节点的话)的值;
STL的类priority_queue基于向量实现。
假设 ,s(x) 是节点x到其子树的外部节点的所有路径最短的一条;
w(x) 是节点x为根的子树的内部节点数目;
高度优先左高树: 当且仅当其任何一个内部节点的左孩子的s值都大于或等于右还是的s值,用于构造可以合并的优先级队列。
重量优先左高树: 当且仅当其任何一个内部节点的左孩子的w值都大于或等于右还是的s值
霍夫曼树: 当用n个节点(都做叶子节点且有各自权值)试图构建一棵树,构建的树的带权路径长度最小。
六、竞赛树
七、平衡搜索树
定义:
搜索树:
- 若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值
- 若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值
- 左、右子树也分别为二叉搜索树
平衡树:
- 任一结点的左右子树均为AVL树
- 根结点左右子树高度差的绝对值不超过1
- 插入节点涉及(RR、RL、LR、LL型旋转)
红黑树(二叉平衡搜索树):
RB1 :根节点和所有外部节点都是黑色
RB2:在根至外部节点路径上,没有连续两个节点是红色
RB3:在所有根至外部节点路径上,黑色指针数目相同。
适用与小型字典场景,内存上检索
B 树和B+树
- m阶B-树是一个m叉搜索树
- 根节点至少有2个孩子 除根节点外,所有内部节点至少有[m/2]个孩子
- 所有外部节点在同一层
- 当在一个饱和节点插入一个新元素时,需分裂该节点
- 二叉B-树是满二叉树
B+树
- 根结点至少两棵子树,其他每个分支结点至少有⌈m/2⌉棵子树
- 每个关键字都应该出现在其对应子结点中,且每个结点都按照从小到大的顺序排列
- 所有外部结点包含全部关键字及指向相应记录的指针。同时外部结点将关键字从小到大顺序排列,并将外部结点按大小顺序链接。
- B+树所有的叶子节点数据构成了一个有序链表
B树和B+树比较
B树优势: 如果经常访问的数据离根节点很近,而B树的非叶子节点本身存有关键字其数据的地址时,访问效率较高。
B+树优势: B+树的层级更少 \B+树查询速度更稳定 \B+树天然具备排序功能 \B+树全节点遍历更快