数据结构与算法 简记

2024-04-30 09:32
文章标签 算法 数据结构 简记

本文主要是介绍数据结构与算法 简记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当有一个出栈,有一个就进栈的情况,可以用一个数组的两端来存储两个栈
用栈可以消除递归
为什么我的迭代比递归慢呢?
二叉树
满二叉树
节点要么是有两个子节点,要么就是叶子节点
Huffman编码就是满二叉树
特性:非空满二叉树的叶节点等于分支节点数加1
完全二叉树
新增节点都是从左到右,添加叶子节点,直到一层添加满,再起一层。
堆就是完全二叉树,堆经常用来实现优先队列和外排序算法。
完全二叉树直接用数组实现最紧凑
指针方式实现
叶子节点和分支节点是否使用相同的结构这点很重要,有些应用分支节点不存储数据,还有一些应用分支节点和叶子节点存储不同的数据
二叉树
删除:
  • 先查找,没有找到就放弃删除
  • 当待删除节点没有子节点,直接删除;
  • 当待删除节点只有一个节点,直接将子树指向待删除节点的父节点
  • 当待删除有两个节点,如果二叉树不允许重复元素出现,则将左子树的最大值或右子树的最大值代替待删除节点即可;但是如果允许重复元素出现,则只能用右子树最小值代替,因为左子树可能出现二个相同的元素,替换之后,左子树就出现了和父节点相同值得元素,这样是不允许的,因为相同的值我们要插入有子树
插入:
找到需要放的叶子节点,把parent指针指向叶子节点成为新的叶子节点
平衡二叉树
AVL
伸展树
堆(最大堆)
定义:父节点把所有子节点都大的完全二叉树,两个子节点之间没有大小关系限制
插入:
放在数组最后
如果比父节点小,则插入完成
如果比父节点大,则和父节点交换,然后再继续比较父节点,直到最后小于父节点
删除:
删除本身,用数组的最后一个填充,如果不满足堆性质,则下拉即可
多叉树
父节点,指向最左子节点和右兄弟节点
还可以用来表示森林,各根节点看做兄弟
树的顺序表示法
节省空间,方便把树序列化存储于磁盘或用于网络传输,特别是在分布式环境下,这种结构方便树结构的重建
用先序遍历方法遍历树,空节点用null表示,这样就实现了树的顺序表示法
空节点的数目=非空节点数目+1
内排序
简单低效率排序(n平方)
  • 插入排序
从第二个元素开始,依次和前面的元素比较,如果比前面小则交换,每一轮下来,前面都是排好序的
优势:对于已经接近排好序的序列,几乎可以接近为零的移动
  • 冒泡排序
从最后一个元素开始,依次和前面的元素比较,每一轮冒泡出一个最小的元素放在数组前面
  • 选择排序
选择排序其实就是冒泡排序,只是每次比较不交换元素,只记录最小值的下标,最后才把最小值交换到前面,交换次数比冒泡排序少,特别适合字符串或者其他大数据交换代价大的场景
希尔排序
是对插入排序的改进,不稳定的排序;虽然数据量特别大的情况下没有快速排序快,但是实现简单,在中等规模的场景比较适合,最差情况和最好情况相差不大;
算法思想:先对下标相隔1的排序(插入排序),然后在对相隔2,相隔4,相隔8,相隔16,直到达到数组长度
快速排序
是对冒泡排序的改进,不稳定的排序,分治思想;在大数据量下是最快的排序算法
算法思想:把数据分为两份(不一定均分),其中一份的所有数据比另一份数据的所有数据都小,然后递归每一份子数据
归并排序
基于bst(二叉排序树),稳定的排序,分治思想;速度仅次于快速排序
算法思想:先使子序列有序,再使子序列间有序
堆排序
基于选择排序,不稳定排序,分为大根堆、小根堆,比快速排序慢一个常数因子,但是堆排序最适合外排序,因为它建堆很快
左节点2i+1,右节点2i+2,最后一个非叶子节点为:arr.length/2 - 1
算法思想:
    1. 将无序序列构建成一个大顶堆。从最后一个非叶子节点开始,比较是否大于子节点,不大于和的话,就和最大的子节点交换,然后递归看交换了的子节点是否满足堆,否则就开始第二个非叶子的判断
    2. 将堆顶元素和末尾元素交换,第二次就和倒数第二个元素交换
    3. 重新调整堆结构,然后重复上面两个步骤
分配排序
桶排序,数的大小直接作为数组下标
外排序
简单外排序
采用双缓冲,两个输入缓冲,两个输出缓冲
数据最开始每个关键码算作一个有序串,第一轮把把关键码组合成有两个关键码的有序串,第二轮是四个关键码的有序串,第三轮是八个关键码的有序串,直到最后只剩一个有序串
两个有序串怎么合并成一个字符串?
首先取出两个串第一个关键码,这样可以得到最小关键码,这样剩下的关键码和另一个有序串的下一个关键码比较,得到第二小的关键码,以此类推
置换选择排序
是对简单外排序的两个串合并的优化,用一个长度为n的数组做堆的
首先建立一个满数组的小根堆,然后把堆顶关键码输出,这样可以新进来一个关键码,如果关键码比刚才堆顶的小,就放到数组最后,作为下一个堆的元素,这轮就不输出,否则就放到堆顶,重新调整堆,输出最当前的最小关键码
多路归并排序
是在置换选择排序的基础上继续优化,把两个串的合并,改为多个串的合并
检索技术
二分查找
自组织线性表
最不频繁使用(LFU)
最近最少使用(LRU)
转置,使用一次就前进一下
位图
散列表
索引
平衡二叉树操作
左旋:x节点的右子树y逆时针旋转,成为x节点的父节点,同时y的左子树成为x的右子树
右旋:x节点的左子树y顺时针旋转,成为x节点的父节点,同时y的右子树成为x的左子树
AVL树
平衡二叉树,允许任意节点的左右子树高度最多相差1
左左结构:右旋
右右结构:左旋
左右结构:左旋之后右旋
右左结构:右旋之后左旋
红黑树
是一种平衡二叉查找树,不像AVL那样严格平衡,执行插入所需开销比AVL树小,平均深度和AVL一样,两个兄弟子树的高度比不会超过两倍
特性:
每个节点要么红色,要么黑色
根节点是黑色
红色节点的孩子必须是黑色(所以黑色节点的孩子可以为黑色)
每个节点到最后一层节点的左右子树包含的黑色节点数目相同
插入(自下而上):
    1. 涂成红色(因为涂成黑色必然导致黑路径路大)
    2. 如果父节点是黑色,则插入完成
    3. 如果父节点是红色,父节点的兄弟节点是黑色,可以采用左旋右旋或者左右旋的方式解决
    4. 如果父节点是红色,父节点的兄弟节点也是红色,把父节点和父节点的兄弟节点变成黑色,祖父节点变为红色,由于祖父的父节点也可能为空红色,所以要向上回溯
插入(自上而下):
在自下而上插入的d步骤改为自上而下,遇到两个红色兄弟节点,就把红色节点改为黑色,父节点改为红色,如果父节点的祖父节点也为红色,则执行一次上面的c步骤
删除:
自上而下进行,每一次删除都可以替换为删除一个叶节点
如果叶节点是红色的,直接删除

伸展树:
是一颗二叉树,但是插入的时候不进行平衡调整,在进行访问的时候才进行调整,不是平衡二叉树
访问到的节点,向上回溯,执行像AVL树一样的旋转
好处:不仅把访问节点移动到了根处,而且还把访问路径上的大部分节点的高度降低了一半
2-3树
内部节点可以有最多两个关键码和最多三个叶节点,叶节点都在最下层,左子树的值小于左关键码,中子树大于等于左关键码,小于右关键码,右子树的值大于等于右关键码
2-3树就是一个3阶B树
B树
特性:
  • 数据存在树叶上(代表一个磁盘区块)
  • 根或者是叶节点,或者至少有两个子女
  • 每个内部节点最多有m-1个关键码
  • 每个内部节点有ceiling(m/2)到m个子女
  • 所有的叶节点在树的同一层,并有floor(L/2)和L之间个数据项
真实应用中,为了填充满一个磁盘块,一般都是大于100个子女
插入:
  • 沿根节点向下确定是放在哪个叶节点
  • 如果叶节点没满就直接放入
  • 如果满了,就要拆分成两个叶节点,同时更新父节点索引
  • 如果父节点也满了,继续向上分解直到根节点
  • 如果节点满了,就分成两个节点,这就是为什么根节点只要最少两个子节点就行,插入可以增加数的高度
删除:
  • 找到节点所在的叶节点,如果删除后大于半满,就直接删除
  • 如果小于半满,就要邻节点领养
  • 如果领养导致父节点索引小于半满,则采用相同的领养策略
  • 如果根节点小于一个节点,则删除根节点,所以删除节点,可以降低树的高度
B+树
特性:
是B树的变体
叶子节点一般链接起来,形成一个双链表

这篇关于数据结构与算法 简记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/948501

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为