数据结构与算法
一、基础知识
1. 数据结构优缺点对比
1.1 对比表格
数据结构 | 优点 | 缺点 | 出现 |
---|---|---|---|
数组 | ①查询复杂度O(1): 通过索引可以在常数时间内(O(1))访问任意元素;②空间局部性好: 数据在内存中是连续存储的,有利于缓存 | ①固定大小: 初始化后大小固定,无法动态调整。②插入和删除效率o(n): 在中间位置插入或删除元素需要移动大量元素 | 下标寻址十分迅速,但是内存有限,数组长度有限;后来提出了二分查找,二分查找要求有序,但是增删改查频繁的结构,数据仍然不会被考虑 |
链表 | ①动态大小: 可以动态调整大小,不需要预先分配固定内存。②插入和删除高效O(1) | ①访问效率低O(n): 需要从头开始遍历,查找某个元素的时间复杂度为O(n)。②额外内存开销: 每个节点需要存储额外的指针信息。 | 不适合进行查找 |
哈希表 | ①插入、删除和查找的时间复杂度为O(1);②高效: 适合用于需要快速查找的场景,如数据库索引 | ①冲突处理: 需要处理哈希冲突,常见的方法有链地址法和开放地址法;②不保证顺序: 数据存储没有顺序,遍历顺序不确定 | 数组和链表的折中,同时它的设计依赖散列函数的设计,数组不能无限长、链表也不适合查找,所以也不适合大规模的查找 |
栈 | ①插入删除O(1);②用途广泛: 用于表达式求值、递归、深度优先搜索等 | ①有限访问 : 只允许在栈顶进行插入和删除操作。②大小固定: 使用数组实现的栈大小固定,使用链表实现的栈有指针开销③栈深度限制:栈的容量有限,导致递归调用过深时程序崩溃 | 不适合随机访问 |
堆 | 是一种图的树形结构,被用于实现有限队列,优先队列是一种数据结构,可以自由添加数据但去除数据要从最小值开始顺序取出,在堆的树形结构中,各个顶点被称为结点,数据就存储在这些结点中 | 每个节点最多有两个子节点;排列顺序必须从上到下,同一行从左到右;堆中某个节点的值总是不大于或不小于其父节点的值;存放数据时,一般会把新数据放在最下面一行靠左的位置。如果最下面一行没有多余空间时,就再往下另起一行,并把数据添加到这一行的最左端 | 堆是一个完全二叉树,堆中某个结点的值总是不大于或不小于其父结点的值 |
队列 | ①**操作简单时间复杂度为O(1)**②公平性: 先进先出(FIFO)的特点保证了公平性 | ①有限访问: 只能访问队头和队尾元素,不能直接访问其他元素,只允许在队尾插入,在队头删除;②大小固定: 使用数组实现的队列大小固定,③动态大小:使用链表实现的队列有指针开销 | 在多线程编程中,队列可以用于线程间通信和任务分发 |
树 | ①二叉树 :插入、删除、查找:平均情况logn,最坏情况n(退化为链表),结构简单,容易实现,可能退化为链表。②平衡二叉树 :高度差不超过1的二叉树,包括AVL树和红黑树-插入、删除、查找logn, |
③完全二叉树:插入、删除logn,可以用数组表示,位置关系简单,空间利用率不高;④二叉搜索树:插入、删除、查找:平均情况logn,最坏情况n;⑤平衡二叉搜索树:AVL树、红黑树,插入、删除、查找logn,实现较为复杂,需要维护树的平衡性 | ⑤B和B+:插入、删除、查找logn,适用于数据库和文件系统,支持高效的磁盘读写,现复杂度较高,尤其是节点的分裂和合并操作 |
图 | ①表达能力强: 可以表示复杂的关系,如网络连接、社交网络。②**灵活: 支持多种遍历和搜索算法,如深度优先搜索、广度优先搜索 | ①存储复杂 邻接矩阵和邻接表的存储方式各有优缺点,选择合适的存储方式需要权衡空间和时间。②算法复杂图的许多算法复杂度高,理解和实现起来较困难 |
1.2 树对比表格
类型 | 定义 | 优劣 | 用途 |
---|---|---|---|
树 | ①每个节点有零个或多个子节点②没有父节点的节点称为根节点③每一个非根节点有且只有一个父节点④除了根节点外,每个子节点可以分为多个不相交的子树 | 路由算法:用于网络路由协议,如最短路径树。社交网络分析:表示用户关系网络,用于社交网络分析和推荐系统。 | |
二叉树 | ①二叉树定义:最多有两颗子树的数对被称为二叉树;②满二叉树:二叉树中所有的非叶子结点的读都是2,且叶子结点都在同一层次上;③完全二叉树:一个二叉树与满二叉树前m个结点的结构相同 | 分类:1)满二叉树2)全二叉树;遍历:先/中/后/层/序遍历; | 搜索:DBS/BFS |
二叉查找树 | 是一颗空树或者满足下列性质的二叉树:①若left!=null,则left<root;②若right!=null,则right<root;③任意节点的左右子树也分别为二叉查找树 | 优势在于查找,插入的时间复杂度较低为(ologn) | 二叉树是基础的数据结构,用于构建更为抽象的数据结构,比如集合、多重级、关联数组 |
平衡二叉树 | ①可以为空;②根节点的左右子树深度只差不超过1;③left、right也是AVL;④平衡二叉树的所有节点的平衡因子只可能是-1,0,1 | 二叉查找树的平均查找长度与树的深度有关,所以需要找出一个1查找平均长度最小的一棵 |
|
红黑树 | ①是AVL树;②每个node非黑即红;③叶子节点都是黑;④一个node是红的,那么他的儿子都是黑的;⑤叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点 | 牺牲了部分平衡性来减少插入和删除操作的旋转次数 | 用途c++中的map&set实现;linux进程调度,管理进程控制块;epoll内核的实现;nginx红黑树管理timer |
哈夫曼树 | ①将所有左,右子树都为空的作为根节点;②在森林中选出两棵根节点的权值最小的树作为一棵新树的左,右子树,且置新树的附加根节点的权值为其左,右子树上根节点的权值之和③从森林中删除这两棵树,同时把新树加入到森林中④重复2,3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树 | 最优二叉树:是一种带权路径长度最短的二叉树 | 用途:哈夫曼编码 |
B树 | ①根结点至少有两个子女②每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m③每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m④所有的叶子结点都位于同一层⑤每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划 | 一种自平衡的树,能够保持数据有序 |
用于读写相对大的数据块的存储系统,例如磁盘 |
B+树 | ①在B树基础上,为叶子结点增加链表指针(B树+叶子有序链表),所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中`② 所以同样大小的节点,b+树相对于b树能够有更多的分支,使得这棵树更加矮胖,查询时做的IO操作次数也更少。 | B+ |