数据结构与算法
2021-11-12 23:51:48   160  举报             
     
         
 AI智能生成
  数据结构与算法是计算机科学的核心领域,它们为解决实际问题提供了基础工具和方法。数据结构是用于存储和组织数据的特定方式,如数组、链表、栈和队列等,而算法则是一系列步骤来执行特定任务或解决特定问题,如排序、搜索和图遍历等。通过选择合适的数据结构和算法,可以有效地提高程序的性能和效率。在软件开发中,熟练掌握数据结构与算法是成为一名优秀程序员的关键要素。
    作者其他创作
 大纲/内容
  线性数据结构    
     数组    
     优点
    
     按照索引,查询/遍历速度快  
     缺点
    
     大小固定,创建后无法扩容
  
     只能存储一种类型数据
  
     添加删除速度慢  
     适用场景    
     频繁查询,数据量不大,少增删操作
  
     栈    
     特殊的线性结构,只能在一端进行操作
  
     特点    
     先进先出  
     适用场景
    
     常用于实现递归方面的操作;如:斐波那契数列  
     队列    
     特殊的线性结构,一端操作数据入队,一端操作数据出队
  
     特点    
     先进先出
  
     适用场景    
     先进先出特点,多线程阻塞队列中,常使用
  
     链表    
     链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现
  
     根据指针指向分类    
     单向链表  
     双向链表  
     循环链表  
     优点
    
     不需要初始化容量,可以任意加减元素;
加减元素只需要更改前后指针
    加减元素只需要更改前后指针
 缺点
    
     含有大量指针域(每个节点数据都有),内存消耗高;
遍历元素需要遍历链表,比较耗时
    遍历元素需要遍历链表,比较耗时
 适用场景    
     数据量少,频繁增删元素  
     串
    
     概念
  
     结构  
     匹配算法
(字符串匹配算法)
    (字符串匹配算法)
 BF算法
  
     KMP算法  
     算法    
     排序    
     插入排序    
     直接插入排序
           
     对于给定的一组记录,初始时假定第一个记录自成一个有序的序列,其余的记录为无序序列;
  
     从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直至最后一个记录插入到有序序列为止。  
     希尔排序
(缩小增量排序)       
    (缩小增量排序)
 把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。
随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。
  
    随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。
 交换排序
    
     冒泡排序           
     快速排序           
     使用分治法策略    
     选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比另外一部分的所有数据都要小。然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。  
     选择排序    
     简单选择排序     
      
     对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将记录与第一个记录的位置进行交换;接着对不包括第一个记录以外的其他记录进行第二轮排序,得到最小的记录并与第二个记录进行位置交换;重复该过程,直到进行比较的记录只有一个为止。  
     堆排序     
      
        将序列构造成一棵完全二叉树 ;
把这棵普通的完全二叉树改造成堆,便可获取最小值 ,输出最小值 ;
删除根结点,继续改造剩余树成堆,便可获取次小值 ,输出次小值 ;
重复改造,输出次次小值、次次次小值,直至所有结点均输出,便得到一个排序 。
    把这棵普通的完全二叉树改造成堆,便可获取最小值 ,输出最小值 ;
删除根结点,继续改造剩余树成堆,便可获取次小值 ,输出次小值 ;
重复改造,输出次次小值、次次次小值,直至所有结点均输出,便得到一个排序 。
 归并排序           
     是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)
递归深度为log2n
  
    递归深度为log2n
 归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。java中Arrays.sort()采用了一种名为TimSort的排序算法,就是归并排序的优化版本。从上文的图中可看出,每次合并操作的平均时间复杂度为O(n),而完全二叉树的深度为|log2n|。总的平均时间复杂度为O(nlogn)。而且,归并排序的最好,最坏,平均时间复杂度均为O(nlogn)。  
     基数排序
     
      
     (1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中
(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
    
    (比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
 不从最高位开始排序的原因,主要是出于空间的考虑,
因为如果按照最高位开始排序,则之后的地位都需要创建一个完整的基数排序空间,空间占用量成指数增长
  
    因为如果按照最高位开始排序,则之后的地位都需要创建一个完整的基数排序空间,空间占用量成指数增长
 拓扑排序    
     将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列。  
     查找    
     概念  
     线性表查找
    
     顺序查找
  
     二分查找
  
     分块查找
  
     树形查找
    
     二叉树查找  
     AVL树查找
  
     B-树  
     B+树  
     哈希查找
    
     概念
  
     冲突解决    
     拉链法  
     图论算法  
     贪婪算法  
     分治算法  
     动态规划
  
     随机化算法
  
     回溯算法  
     高级数据结构    
     自顶向下伸展树
  
     红黑树  
     确定性跳跃表  
     AA树
  
     treap树
  
     k-d树
  
     配对堆  
     散列表    
     根据键值(key/value)进行访问的数据结构;
通过key/value来映射到集合中的元素,这样可以很快找到集合中的元素
  
    通过key/value来映射到集合中的元素,这样可以很快找到集合中的元素
 堆    
     定义    
     最大堆
(大根堆)
    (大根堆)
 堆中某个节点总是不大于父节点  
     最小堆
(小根堆)
    (小根堆)
 堆中某个节点总是不小于(最小堆)父节点  
     性质    
     堆的常用结构使用二叉树表示,不特指的话为一棵完全二叉树,通常不必用指针,
而是用数组来实现堆的存储堆:
数组起始单元为1,在数组中按照完全二叉树的层序存储,
根节点放在下标为1的位置中
对于下标为i的结点,其父结点的下标为i/2取整,反过来,i的左右结点分别是2i和2i+1
  
    而是用数组来实现堆的存储堆:
数组起始单元为1,在数组中按照完全二叉树的层序存储,
根节点放在下标为1的位置中
对于下标为i的结点,其父结点的下标为i/2取整,反过来,i的左右结点分别是2i和2i+1
 常用堆    
     二叉堆
  
     斐波那契堆  
     注意    
     堆的根节点中存放的是最大或者最小元素,但是其他节点的排序顺序是未知的。    
     例如,
在一个最大堆中,最大的那一个元素总是位于 index 0 的位置,但是最小的元素则未必是最后一个元素。
--唯一能够保证的是最小的元素是一个叶节点,但是不确定是哪一个。
  
    在一个最大堆中,最大的那一个元素总是位于 index 0 的位置,但是最小的元素则未必是最后一个元素。
--唯一能够保证的是最小的元素是一个叶节点,但是不确定是哪一个。
 可以使用普通树来模拟堆,但是那对空间是极大的浪费。  
     并不是每一个最小堆都是一个有序数组!要将堆转换成有序数组,需要使用堆排序。  
     实现
    
     堆仅仅使用一个数据来存储数组,且不使用指针  
     基本操作    
     shiftUp()    
     如果一个节点比它的父节点大(最大堆)或者小(最小堆),那么需要将它同父节点交换位置。
这样是这个节点在数组的位置上升
  
    这样是这个节点在数组的位置上升
 shiftDown()    
     如果一个节点比它的子节点小(最大堆)或者大(最小堆),那么需要将它向下移动。这个操作也称作“堆化(heapify)”  
     常见应用
    
     构建优先队列  
     因为堆有序,常用来做数组排序——堆排序  
     树    
     概述
    
     定义    
     1.每个节点有零个或多个子节点
2.没有父节点的节点称为根节点;
3.每一个非根节点有且只有一个父节点;
4.除了根节点外,每个子节点可以分为多个不相交的子树;
  
    2.没有父节点的节点称为根节点;
3.每一个非根节点有且只有一个父节点;
4.除了根节点外,每个子节点可以分为多个不相交的子树;
 术语    
     节点的度    
     一个节点含有的子树的个数称为该节点的度  
     叶节点/终端节点    
     度为0的节点称为叶节点  
     非终端节点/分支节点    
     度不为0的节点  
     节点的层次    
     从根开始定义起,根为第1层,根的子节点为第2层,以此类推  
     树的高度或深度    
     树中节点的最大层次  
     森林    
     由m(m>=0)棵互不相交的树的集合称为森林  
     遍历方式    
     前序遍历    
     父左右  
     中序遍历    
     左父右  
     后续遍历    
     左右父  
     层序遍历    
     从根节点开始,一层层往下  
     常见树
    
     二叉树     
      
     概述    
     定义
    
     1.每个节点最多有两个子树,节点的度最大为2;
2.左子树和右子树是有顺序的,顺序不能颠倒;
3.即使某个节点只有一个子树,也要区分左右节点
    2.左子树和右子树是有顺序的,顺序不能颠倒;
3.即使某个节点只有一个子树,也要区分左右节点
 第i层至多有2^(i-1)个结点;
深度为k的二叉树至多有2^k-1个结点
    深度为k的二叉树至多有2^k-1个结点
 特点
    
     二叉树是数组和链表的折中方案,
增加、删除速度都快,并且对查询也有算法优化;
在动态处理大批量数据的时候很有用
  
    增加、删除速度都快,并且对查询也有算法优化;
在动态处理大批量数据的时候很有用
 满二叉树     
      
     一棵深度为k且有2^k-1(2的k次幂减1)个结点的二叉树称为满二叉树  
     完全二叉树     
      
     深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应  
     二叉排序树     
      
     二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
    - 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
- 它的左、右子树也分别为二叉排序树。
 存在的问题    
     对于一般的二叉搜索树(Binary Search Tree),其期望高度(即为一棵平衡树时)为log2n,其各操作的时间复杂度O(log2n)同时也由此而决定;
在某些极端的情况下(如在插入的序列是有序的时),二叉搜索树将退化成近似链或链,此时,其操作的时间复杂度将退化成线性的,即O(n)。
原因:由于在删除时,我们总是选择将待删除节点的后继代替它本身,这样就会造成总是右边的节点数目减少,以至于树向左偏沉。
这同时也会造成树的平衡性受到破坏,提高它的操作的时间复杂度
    在某些极端的情况下(如在插入的序列是有序的时),二叉搜索树将退化成近似链或链,此时,其操作的时间复杂度将退化成线性的,即O(n)。
原因:由于在删除时,我们总是选择将待删除节点的后继代替它本身,这样就会造成总是右边的节点数目减少,以至于树向左偏沉。
这同时也会造成树的平衡性受到破坏,提高它的操作的时间复杂度
 自平衡二叉搜索树    
     AVL树
     
      
     概述    
     它或者是一棵空树,或者是具有下列性质的二叉树:
它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。
(注:平衡二叉树应该是一棵二叉排序树)
  
    它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。
(注:平衡二叉树应该是一棵二叉排序树)
 n个结点的AVL树最大深度约1.44log2n  
     查找、插入和删除在平均和最坏情况下都是O(logn)  
     增加和删除可能需要通过一次或多次树旋转来重新平衡这个树;
这个方案很好的解决了二叉查找树退化成链表的问题,
把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。
但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多
  
    这个方案很好的解决了二叉查找树退化成链表的问题,
把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。
但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多
 AVL树的自平衡操作——旋转    
     左左/右右    
     单旋转    
     左左情况,单旋转自平衡处理  
     左右/右左    
     多旋转    
     子主题  
     2-3树    
     性质    
     1.满足AVL树的性质;
2.节点可以存放1个或2个元素;
3.每个节点有两个或三个子节点。
    2.节点可以存放1个或2个元素;
3.每个节点有两个或三个子节点。
 2-3树本质上也是一棵搜索树,和二叉搜索树的区别在于,2-3的节点可能存放 2 个元素,而且每个节点可能拥有 3 个子节点。  
     2-3树存在以下两种节点:2-节点(存在两个子节点)和3-节点(存在3个子节点)  
     红黑树
(RB-tree)
    (RB-tree)
 概述    
     自平衡二叉查找  
     可以在O(logn)时间内做查找,插入和删除  
     性质    
     在二叉查找树强制的一般要求以外增加:
1.节点是红色或黑色;
2.根是黑色;
3.所有叶子都是黑色(叶子是NIL节点);
4.每个红色节点下有两个黑节点(每个叶子到根的路径上不能有两个连续的红色节点);
5.从任意节点到每个叶子节点的简单路径上有相同节点的黑色节点。
  
    1.节点是红色或黑色;
2.根是黑色;
3.所有叶子都是黑色(叶子是NIL节点);
4.每个红色节点下有两个黑节点(每个叶子到根的路径上不能有两个连续的红色节点);
5.从任意节点到每个叶子节点的简单路径上有相同节点的黑色节点。
 SBT  
     Splay  
     Treap  
     Treap
(树堆)
  
    (树堆)
 B树
(B-树)
     
      
    (B-树)
 概念    
     是一种平衡的多路查找树。B-树的阶是所有结点的孩子结点树的最大值。
B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个),
数据库索引技术里大量使用者B树和B+树的数据结构
  
    B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个),
数据库索引技术里大量使用者B树和B+树的数据结构
 规则    
     一棵m阶B-树,或为空树,或为满足下列特性的m叉树:
A:为指向子树根结点的指针,
K:为关键字,且Ai-1所指子树中所有结点的关键字均小于Ki,An所指子树中所有结点的关键字均大于Kn;
  
    - 1)树中每个结点至多有m棵子树;
- 2)若根节点不是叶子节点,则至少有两棵子树;
- 3)除根之外的所有非终端结点至少有[m/2]()向上取整)棵子树;
- 4)所有的非终端结点中包含下列信息数据:(n,A0,K1,A1,K2,A2,…,Kn,An),
A:为指向子树根结点的指针,
K:为关键字,且Ai-1所指子树中所有结点的关键字均小于Ki,An所指子树中所有结点的关键字均大于Kn;
- 5)所有的叶子结点都出现在同一层次上,并且不带信息
 多叉平衡查找树  
     参考    
     从B树、B+树、B*树谈到R 树  
     平衡二叉树、B树、B+树、B*树 理解其中一种你就都明白了  
     B+树
     
      
     概念    
     B+树是B树的一个升级版,相对于B树来说B+树更充分的利用了节点的空间,让查询速度更加稳定,其速度完全接近于二分法查找  
     规则    
     1)B+跟B树不同B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加;
2)B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;
3)B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。
4)非叶子节点的子节点数=关键字数(来源百度百科)
(根据各种资料 这里有两种算法的实现方式,另一种为非叶节点的关键字数=子节点数-1(来源维基百科),
虽然他们数据排列结构不一样,但其原理还是一样的Mysql 的B+树是用第一种方式实现);
  
    2)B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;
3)B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。
4)非叶子节点的子节点数=关键字数(来源百度百科)
(根据各种资料 这里有两种算法的实现方式,另一种为非叶节点的关键字数=子节点数-1(来源维基百科),
虽然他们数据排列结构不一样,但其原理还是一样的Mysql 的B+树是用第一种方式实现);
 分裂    
     当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;
只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针。
  
    只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针。
 应用场景    
     数据库索引  
     B*树    
     概念    
     规则    
     B*树是B+树的变种,相对于B+树他们的不同之处如下:
(1)首先是关键字个数限制问题,B+树初始化的关键字初始化个数是cei(m/2),b*树的初始化个数为(cei(2/3*m))
(2)B+树节点满时就会分裂,
而B*树节点满时会检查兄弟节点是否满(因为每个节点都有指向兄弟的指针),
如果兄弟节点未满则向兄弟节点转移关键字,
如果兄弟节点已满,则从当前节点和兄弟节点各拿出1/3的数据创建一个新的节点出来;
  
    (1)首先是关键字个数限制问题,B+树初始化的关键字初始化个数是cei(m/2),b*树的初始化个数为(cei(2/3*m))
(2)B+树节点满时就会分裂,
而B*树节点满时会检查兄弟节点是否满(因为每个节点都有指向兄弟的指针),
如果兄弟节点未满则向兄弟节点转移关键字,
如果兄弟节点已满,则从当前节点和兄弟节点各拿出1/3的数据创建一个新的节点出来;
 特点    
     在B+树的基础上因其初始化的容量变大,使得节点空间使用率更高,
而又存有兄弟节点的指针,可以向兄弟节点转移关键字的特性使得B*树额分解次数变得更少;
  
    而又存有兄弟节点的指针,可以向兄弟节点转移关键字的特性使得B*树额分解次数变得更少;
 分裂    
     当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针。  
     B*树分配新结点的概率比B+树要低,空间使用率更高。  
     R树  
     哈夫曼树    
     概念
    
     在叶子结点和权重确定的情况下,带权路径长度最小的二叉树,也被称为最优二叉树。  
     结构  
     适用场景  
     典型运用    
     哈夫曼编码  
     trie 树(字典树)    
     前缀树,典型运用:关键字过滤  
     图    
     概念    
     图是由结点的有穷集合V和边的集合E组成。
在图结构中常常将结点称为顶点,
边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。
  
    在图结构中常常将结点称为顶点,
边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。
 术语
    
     定点  
     边
    
     边上带权重的为带权图  
     按照顶点方向划分    
     有向图  
     无向图  
     图的表示    
     邻接矩阵    
     无向图  
     有向图  
     缺点    
     占用空间太大  
     邻接表    
     图的每一个顶点都是一个链表的头节点,其后连接着该顶点能够直接达到的相邻顶点  
     逆邻接表
    
     每一个顶点作为链表的头节点,后继节点所存储的是能够直接达到该顶点的相邻顶点  
     十字链表    
     邻接表+逆邻接表=十字链表    
     十字链表  
     邻接多重表  
     边集数组  
     遍历
    
     深度优先遍历    
     利用栈实现  
     广度优先遍历    
     利用队列实现  
     应用
    
     最小生成树
  
     最短路路径
    
     无权图    
     广度优先算法  
     带权图    
     迪杰斯特拉算法
  
     多源最短路径    
     佛洛依德算法  
     拓扑排序  
     关键路径
  
    
 
 
 
 
  0 条评论
 下一页
  
   
   
   
   
  
  
  
  
  
  
  
  
  
  
 