链表
链表属于最基本的数据结构。由于许多数据结构既可以用数组也可以用链表来实现,所以通常会与数组进行比较,但它们各有优缺点
链表通常由一组代表一个序列的节点组成。 每个节点包含存储的任意类型实际数据以及指向序列中下一个节点的指针。特殊的,还有双向链表,其中每个节点都有两个指针,分别起到承前启后的作用。
链表中最基本的操作是插入链表、删除链表以及查询链表。下表为链表的时间复杂度:
堆栈
堆栈属于一种基本的数据结构,你只能在堆栈的顶部插入或删除项目。这有点像一堆书, 如果你想看堆栈中间的一本书,你必须先将它上面上面的所有书移走。
堆栈遵循后进先出,也就是说你最后放入堆栈的项目是第一个出栈的项目
对堆栈主要有三种操作:push,即插入新内容到堆栈;pop,从堆栈中删除一项内容;PIp,显示堆栈的内容。
堆栈时间复杂度:
队列
你可以把队列想象成一家杂货店里排队买单的人,队伍中第一个人先被服务。
队列遵循先进先出,也就是说一旦你想添加了新元素,你要想删除它,必须先删除它前面的的所有元素。队列只有两个主要操作:入队和出队。 入队,就是将新的内容插入队列后面,而出队就是前面所有的内容。
队列时间复杂度:
集合
以集合形式存储的数据结构中不存在任何特定的顺序,也不存在重复的值。除了向集合中添加新元素或者删除元素之外,还有一些重要的集合函数可以进行两组集合的处理。
并集,将来自两个不同集合的所有元素结合起来作为新集合返回(不重复).
交集,给定两个集合,此函数返回另一个集合,包含属于两个集合的共同部分。
差集,给定两个集合,此函数返回另一个集合,其中各个元素属于一个集合,但不属于另一个集合。
子集 ,返回一个布尔值,显示一个集合中的所有元素是否包含在不同的集合中。
MAP
Map是容器的一种,也属于一种数据结构,它将数据存储在键/值对中,且每个键是唯一的。 map有时也称为关联数组或字典,通常被用于快速查找数据。 Map可以进行以下操作:
在集合中增加一对
从集合中删除一对
修改现有的一对
查找与特定键相关联的值
二叉搜索树
树是由节点组成的数据结构,它具有以下特征:
每棵树都有一个根节点(位于顶部)。
根节点具有零个或多个子节点。
每个子节点都有零个或多个子节点。
二叉搜索树还具有额外的两个特征:
每个节点最多有两个子节点.
对于每个节点,它左边的子节点小于当前节点,而右边的子节点则大于当前节点。
每个节点最多有两个子节点。
二叉搜索树允许快速查找、添加和删除内容。 从它的设计结构来看,每次比较后都会跳过树的大约一半内容,因此每次查找、插入或删除需要的操作时间与存储在树中的内容数量的对数成比例。
二叉树时间复杂度:
二叉堆
二叉堆是特殊的树数据结构。形式上看,它从顶点开始,每个节点有两个子节点,每个子节点又各自有自己的两个子节点;数值上看,每个节点的两个子节点都比它大或小。
二叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;最小堆:父结点的键值总是小于或等于任何一个子节点的键值。
在二叉堆上可以进行插入节点、删除节点、取出值最小的节点、减小节点的值等基本操作。不同层之间的顺序很重要,但同一层上节点的顺序无关紧要。 如图所示,你可以看到最小堆的第三层的值是10,6和12,这些数字并不是按照顺序排列的。
二叉堆时间复杂度:
hash哈希和映射
哈希映射是很快的,映射又可以称为字典
哈希表是包含键/值对的地图数据结构,使用散列函数来把关键码值映射到表中一个位置来访问记录,以加快查找的速度。散列函数通常将一个字符串作为输入,并输出一个数值。散列函数对相同的输入提供相同的输出编号。 当两个输入哈希得到相同的数字输出时,称为碰撞。
我们的目标是没有碰撞。所以当你将一个键/值对输入到一个散列表中时,这个键将通过散列函数映射到一个数字,用作值存储的实际键。 当你尝试再次访问相同的密钥时,哈希函数将处理该密钥并返回相同的数字结果,用于查找关联的值。
计算哈希函数的键值的方式有很多种,例如计算输入key的各个字母的ASC码,进行相加。如果出现极大的哈希函数的结果,可以对一个数取余数。 根据新的key,把value放到数组对应的位置。
算法速度非常快,查找的时间复杂度仅为O(1)。执行效率和所用的哈希函数有关系,所以设计的时候需要设计简单的哈希函数。
查找算法速度比较
O(1): hash 速度
O(logN) 二分查找速度
O(N) 线性查找
O(N^2) 冒泡法查找速度
代码
#include <map> // map是一种二叉树映射/字典的数据结构
#includ <hash_map> // C++里面的哈希映射
hash_map<string, int> hm;
hm['Bill'] = 13;
hm['Tom'] = 23;
数组
B树
B树是为硬盘、U盘等外部存储设备使用的平衡树。对降低IO操作次数的时候有优势。许多数据库系统使用B树和其变形。
例如,论文:基于B+树的闪存文件系统…
B树是一种多叉树。
DFS深度优先搜索
利用堆栈
从深度上一溜烟的找,找不到之后往上找别的分支,继续从深度方向找。
为什么使用堆栈?
因为堆栈是先进后出的,找完最左边一侧之后,往上找别的分支,需要后进先出的数据,才能找刚刚处理的数据。
例子:A - B - E- C - D的顺序进行寻找
BFS广度优先搜索
利用队列
从水平上一层一层的找。
为什么使用队列?
先进先出,顺序是从a b c d e这样找下去,和队列的顺序一样