
数据结构与算法
文章平均质量分 91
此生辽阔
这个作者很懒,什么都没留下…
展开
-
数据结构与算法之美-学习笔记(二)
17|跳表:为什么Redis一定要用跳表来实现有序集合?二分查找底层依赖的是数组随机访问的特性,所以只能用数组来实现。如果数据存储在链表中,就真的没法用二分查找算法了吗?对链表稍加改造,就可以得到跳表,支持快速的插入、删除、查找操作为了提高有序链表的存储效率,在链表的基础上,提出一层索引层,对链表建立一级索引如果我们现在要查找某个结点,比如16。我们可以先在索引层遍历,当遍历到索引层中值为13的结点时,我们发现下一个结点是17,那要查找的结点16肯定就在这两个结点之间。然后我们通过索引层结点的do原创 2021-11-01 13:06:23 · 1620 阅读 · 0 评论 -
数据结构与算法之美-学习笔记(一)
01|为什么要学习数据结构和算法?如果不知道这些类库背后的原理,不懂得时间、空间复杂度分析,你如何能用好、用对它们?存储某个业务数据的时候,你如何知道应该用ArrayList,还是Linked List呢?调用了某个函数之后,你又该如何评估代码的性能和资源的消耗呢?我曾经面试过很多大龄候选人,简历能写十几页,经历的项目有几十个,但是细看下来,每个项目都是重复地堆砌业务逻辑而已,完全没有难度递进,看不出有能力提升。久而久之,十年的积累可能跟一年的积累没有任何区别。这样的人,怎么不会被行业淘汰呢?我们原创 2021-07-22 13:47:32 · 1530 阅读 · 2 评论 -
LRU算法学习笔记
LRU算法概念LRU算法在面试中经常遇到重要性可与快排比肩全称:Least Recently Used即最近最久未使用主要应用场景:缓存我们访问数据库的时候,有些数据经常被访问(热点数据),我们把这些数据放在内存中缓存下来,就不用每次都去数据库里面查找,当下一次有同样请求的时候,可以以更快的速度返回既然是把热点数据存在缓存中,那么缓存的容量是有限的,那么容量不足的时候,我们就要考虑剔除一部分数据,那么问题就来了,我们需要考虑剔除哪一部分数据-----就有了LRU算法,剔除一些最近没有访问的数据,达原创 2021-03-15 23:56:12 · 545 阅读 · 0 评论 -
牛客刷题笔记--(队列专项练习)
知识点总结图的拓扑排序 深度优先 关键路径算法用的辅助数据结构是栈树的层序遍历 图的广度优先遍历用的数据结构是队列输入受限 的 双端队列 是指元素只能从 队列 的一 端输入 ,但可以从 队列 的两端 输出;输出受限 的 双端队列 是指只有一端可以进行出队操作而从两端都可以进行入队操作的 队列。题型判断队列元素输入受限 的 双端队列 出队列顺序输出受限 的 双端队列 出队列顺序刷题1 循环队列的存储空间为 Q(1:100) ,初始状态为 front=rear=100 。经过一系列正常的入队原创 2021-01-27 21:27:40 · 6017 阅读 · 1 评论 -
牛客刷题笔记--(栈专项练习)
知识点题型元素的出栈顺序1两个栈共享一片连续内存空间时,为提高内存利用率,减少溢出机会,应把两个栈的栈底分别设在这片内存空间的两端(√)。使用一个数组来存储两个栈,让一个栈的栈底为该数组的始端,另一个栈的栈底为该数组的末端,每个栈从各自的端点向中间延伸2 下列关于栈的叙述中,错误的是 。(I、Ⅲ、Ⅳ)Ⅰ.采用非递归方式重写递归程序时必须使用栈Ⅱ.函数调用时,系统要用栈保存必要的信息Ⅲ.只要确定了入桟次序,即可确定出栈次序Ⅳ.栈是一种受限的线性表,允许在其两端进行操作I的反例:计算斐波拉契原创 2021-01-26 16:34:16 · 6516 阅读 · 0 评论 -
常用的10种算法(一)二分查找、分治算法、动态规划、KMP算法、贪心算法
二分查找算法(非递归)二分查找法只适用于从有序的数列中进行查找(比如数字和字母等),将数列排序后再进行查找二分查找法的运行时间为对数时间O(㏒₂n) ,即查找到需要的目标位置最多只需要㏒₂n步,假设从[0,99]的队列(100个数,即n=100)中寻到目标数30,则需要查找步数为㏒₂100 , 即最多需要查找7次( 2^6 < 100 < 2^7)public class BinarySearchNoRecur { public static void main(String[] ar原创 2021-01-22 17:33:19 · 1022 阅读 · 0 评论 -
牛客刷题笔记--(链表专项练习)
知识点采用二分查找的数据只适合采用顺序存储结构,不适用于链式存储结构。折半查找(二分查找)的要求 1必须采用顺序存储结构 2必须按关键字大小有序排列1 判断一个单向链表中是否存在环的最佳方法是(快慢指针)让快慢指针都从链表表头开始,快指针一次向前移动连个位置,慢指针每次向前移动一个位置。如果快指针到达了NULL,说明不存在环,但如果快指针追上了慢指针,说明存在环。2 某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用(D)存储方式最节省运算时间。单链表仅有头指针的原创 2021-01-19 22:33:10 · 6890 阅读 · 1 评论 -
图、深度优先、广度优先
为什么要有图前面我们学了线性表和树线性表局限于一个直接前驱和一个直接后继的关系树也只能有一个直接前驱也就是父节点当我们需要表示多对多的关系时, 这里我们就用到了图图是一种数据结构,其中结点可以具有零个或多个相邻元素。两个结点之间的连接称为边。 结点也可以称为顶点图的表示方式图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)。邻接矩阵邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵是的row和col表示的是1…n个点邻接表邻接矩阵需要为每个顶点都分原创 2021-01-15 15:22:06 · 892 阅读 · 0 评论 -
多路查找树(2-3树、B树、B+树、B*树)
二叉树的问题分析二叉树的操作效率较高,但是也存在问题, 请看下面的二叉树二叉树需要加载到内存的,如果二叉树的节点少,没有什么问题,但是如果二叉树的节点很多(比如1亿), 就存在如下问题:问题1:在构建二叉树时,需要多次进行i/o操作(海量数据存在数据库或文件中),节点海量,构建二叉树时,速度有影响问题2:节点海量,也会造成二叉树的高度很大,会降低操作速度.多叉树在二叉树中,每个节点有数据项,最多有两个子节点。如果允许每个节点可以有更多的数据项和更多的子节点,就是多叉树(multiway tre原创 2021-01-13 11:29:39 · 678 阅读 · 0 评论 -
平衡二叉树
平衡二叉树首先是一棵二叉排序树平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树, 可以保证查询效率较高。具有以下特点:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。(1)(2)均是平衡二叉树,(3)不是平衡二叉树,因为根节点的左子树的高度为3,右子树的高度为1,左右子树高度差绝对值大于1,不是平衡二叉树。AVL树原创 2021-01-13 10:13:01 · 187 阅读 · 0 评论 -
二叉排序树
先看一个需求给你一个数列 (7, 3, 10, 12, 5, 1, 9),要求能够高效的完成对数据的查询和添加。使用数组数组未排序, 优点:直接在数组尾添加,速度快。 缺点:查找速度慢.数组排序,优点:可以使用二分查找,查找速度快,缺点:为了保证数组有序,在添加新数据时,找到插入位置后,后面的数据需整体移动,速度慢。使用链式存储-链表不管链表是否有序,查找速度都慢,添加数据速度比数组快,不需要数据整体移动。使用二叉排序树二叉排序树介绍二叉排序树:BST: (Binary Sor原创 2021-01-12 16:13:13 · 259 阅读 · 0 评论 -
赫夫曼树介绍、赫夫曼编码、数据压缩、数据解压
基本介绍(1)给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)(weightt path length)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍夫曼树。(2)赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近。赫夫曼树几个重要概念和举例说明路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长原创 2021-01-11 21:17:48 · 384 阅读 · 0 评论 -
牛客刷题笔记--(字符串专项练习)
1 判断下述语句的对错:MFC中CString是类型安全的类 (√)==类型安全就是说,如果两个类型直接要相互转换,必须要显示的转换,不能偷偷摸摸的只用一个等于号就隐式转换了 ==类型安全不是一种类型,是有关类型操作一种规范。如:不让不同类型的数据相互转换int Num =3;string Str=“3”;Num =Str; //错Num=int.Parse(Str);//对类型安全要求可以相互转换的不同类型数据在转换时 显式转换MFC数据类型转换标准库std的string 和MFC类库C原创 2021-01-06 21:04:00 · 3806 阅读 · 0 评论 -
归并排序算法原理及Java实现
快速排序算法思路漫画:什么是快速排序?(完整版)快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列快速排序示意图,以11为基准,把数组分成大于11和小于11的两部分,分别进行排序...原创 2021-01-03 14:53:47 · 489 阅读 · 0 评论 -
快速排序原理及Java实现
漫画:什么是快速排序?(完整版)快速排序-填坑法视频:快速排序算法–填坑法快速排序算法思路(双指针)快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列快速排序示意图,以11为基准,把数组分成大于11和小于11的两部分,分别进行排序现在有5个数,取中间数为基准值,此时中间数是0可以原创 2021-01-02 17:31:20 · 187 阅读 · 1 评论 -
牛客刷题笔记--(数组专项练习1-77)
1 下面哪项是数组优于链表的特点? D方便删除方便插入长度可变存储空间小1: 数组内存空间少比链表少2:数组支持随机访问,链表不具有随机访问的特性3:插入和删除是链表优于数组,数组需要移动被删除或者插入位置之后的元素https://blog.csdn.net/u014082714/article/details/44259029D 链表要保存指向下个节点的指针,占用空间比数组更大2 在C++中,以下定义和初始化的两数组a1和a2,那么下列说法正确的是( D)。a1和a2完全相同原创 2021-01-01 16:50:02 · 21771 阅读 · 0 评论 -
基数排序原理及Java实现
基数排序算法思路图解基数排序(桶排序)介绍:基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法基数排序(Radix Sort)是桶排序的扩展基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。原创 2020-12-31 11:17:29 · 196 阅读 · 1 评论 -
堆排序原理及Java实现
堆排序思路图解图解排序算法(三)之堆排序堆排序详解–大顶堆白话讲排序系列(六) 堆排序(绝对让你明白堆排序!)堆排序基本介绍堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 注意 : 没有要求结点的左孩子的值和右孩子的值的大小关系。每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆大顶堆举例说明我们对堆中的结原创 2020-12-30 17:04:53 · 232 阅读 · 0 评论 -
怎么计算把数组转成完全二叉树之后,二叉树有几层
首先解释一下完全二叉树的概念如果该二叉树的所有叶子节点都在最后一层,并且结点总数= 2^n -1 , n 为层数,则我们称为满二叉树。如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,我们称为完全二叉树。完全二叉树处理最后一层,其余层都是满的,如果有n层,那么前n-1层的元素个数总数为2的(n-1)次方减1于是可以用下面的函数计算把数组转成完全二叉树之后,二叉树有几层 void heapsortfunc(int arr[])原创 2020-12-29 20:00:58 · 993 阅读 · 0 评论 -
顺序存储二叉树
顺序存储二叉树思路图解从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组要求:下图的二叉树的结点,要求以数组的方式来存放 arr : [1, 2, 3, 4, 5, 6, 6]要求在遍历数组 arr时,仍然可以以前序遍历,中序遍历和后序遍历的方式完成结点的遍历顺序存储二叉树代码实现在这里插入代码片需求: 给你一个数组 {1,2,3,4,5,6,7},要求以二叉树前序遍历的方式进行遍历。 前序遍历的结果应当为 1,2,4,5,3,6,7pa原创 2020-12-27 17:19:52 · 150 阅读 · 0 评论 -
树结构基础部分-二叉树前中后序遍历查找删除节点
为什么需要树这种数据结构数组存储方式的分析优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低链式存储方式的分析优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可, 删除效率也很好)。缺点:在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历)树存储方式的分析能提高数据存储,读取的效率, 比如利用 二叉排序树(Binary Sor原创 2020-12-27 15:19:12 · 270 阅读 · 0 评论 -
哈希表(散列)
哈希表的介绍和内存布局散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。把数据先放到哈希表,哈希表类似于redis等缓存层,可以供java程序与数据库进行交互,提升数据查找速度一级缓存不够可以做二级缓存内存布局数组里面的每一个元素存的是一个链表,数组变成链表数组,当我们要查找元素ID的时候,可以先用散列函数得到我们的原创 2020-12-25 16:53:40 · 310 阅读 · 0 评论 -
排序算法原理及Java实现(冒泡、选择、插入、希尔)
初级排序算法选择排序插入排序原创 2020-12-18 11:33:48 · 182 阅读 · 0 评论 -
递归-迷宫回溯问题的分析与实现
步骤:1.先创建一个二维数组模拟迷宫,红色的部分为模拟的墙,使用1表示墙,先把上下左右全置为1可以先遍历输出看一下结果,再把红色的墙部分填1,1就是不能走的地方使用递归回溯给小球找路,如果找到了就返回true,否则返回falsepublic static boolean setWay(int[][]map,int i,int j){}//我们需要传入地图,i,j表示从哪个位置开始出发设置开始点为[1][1],结束点为[6][5],则说明通路找到约定:当地图的[i][j]为0时,表示当前还没有走原创 2020-11-22 13:08:44 · 239 阅读 · 0 评论 -
递归的应用场景和调用机制、递归需要遵守的重要规则
简单地说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得简洁①通过打印问题回顾递归调用的机制public class recursion { public static void main(String[] args) { test(4); } public static void test(int n) { if (n > 2) { test(n - 1);原创 2020-11-17 15:33:13 · 486 阅读 · 2 评论 -
栈实现计算器-栈的前缀中缀后缀表达式
前缀表达式(波兰表达式)前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前举例说明: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6前缀表达式的计算机求值从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果例如: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6 , 针对前缀表达式求值步骤如下..原创 2020-10-14 22:34:06 · 324 阅读 · 0 评论 -
双向链表(一)
双向链表增删改查分析图解单链表存在的问题1查找的方向只有一个,要查找一个节点只能从head开始一个一个地遍历2单向链表不能自我删除,需要靠辅助节点,而双向链表可以实现自我删除分析:双向链表的遍历,添加,删除,修改的思路遍历:和单链表一样,只是可以镶嵌,也可以向后查找添加:(默认添加到双向链表的最后)(1)首先通过遍历找到最后一个节点(2)temp.next=newHeroNode(3)newHeroNode.pre=temp;下图紫色框为newHeroNode修改:原理和单向链表一样原创 2020-09-26 22:31:08 · 187 阅读 · 0 评论 -
链表面试题分析
单链表的反转思路分析当链表为空或者只有一个节点时,无需反转1先定义一个节点reverse=neew heroNode,定义一个辅助变量,用于遍历原来的链表定义一个变量指向当前节点的下一个节点2从头到尾遍历原来的链表,每遍历一个节点,就取出,并放在新链表的最前端,3原来链表的head.next指向reverse.next从尾到头打印单链表思路分析方式1:先反转单链表,然后打印,但是这样会破坏原来单链表的结构,不建议方式2:利用栈,将各个节点压入到栈中,利用栈先进后出的特点,实现逆原创 2020-09-22 22:37:52 · 140 阅读 · 0 评论 -
单链表(二)
思路分析需要按照编号的顺序添加1.找到新添加的节点的的位置,如果添加2号,则需要添加到1号和4号之间,通过辅助节点temp来找(遍历)2.新的节点的next域指向temp的next域3.temp的next域指向新的节点 4.因为是单链表,temp应该位于添加位置的前一个节点5.添加一个标志位标识添加的英雄编号是否存在6.while循环遍历7.比较节点编号大小(temp.next.no>newnode.no?),成立,则新节点插入在temp和temp.next之间...原创 2020-09-13 11:26:11 · 150 阅读 · 0 评论 -
链表(一)插入节点、显示链表
链表介绍如下图,头结点指向地址为150,对应data域的值为a1,next域指向地址为110,,,,,单链表实现1,先定义一个HeroNode类,每一个HeroNode对象就是一个结点类的属性有编号,姓名,昵称,next域需要写构造函数//为了显示方便,重写ToString定义singlelinkedlist管理heronode先初始化一个头结点,这个头结点一般不要动,如果动了,我们就找不到链表的最顶端,这个头结点我们不存放具体的数据插入节点时,(当不考虑编号顺序)我们首先要找到最后一原创 2020-09-11 00:13:18 · 654 阅读 · 0 评论 -
队列、循环队列
特点:先进先出举例:银行排队叫号系统队列是一个有序列表,可以用数组或是链表来实现。用数组实现就是顺序存储,用链表实现就是链式存储遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出数组模拟队列当我们将数据存入队列时称为”addQueue",addQueue 的处理需要有两个步骤:思路分析将尾指针往后移: rear+1, 当front== rear [空]若尾指针rear小于队列的最大下标maxSize-1,则将数据存入rear所指的数组元素中,否则无法存入数据。rear ==原创 2020-08-07 23:46:23 · 226 阅读 · 0 评论 -
数据结构与算法学习资料、网站
3 个学数据结构和算法的网站https://www.cs.usfca.edu/~galles/visualization/Algorithms.htmlhttps://visualgo.net/zhhttps://algorithm-visualizer.org/原创 2020-07-28 16:39:02 · 346 阅读 · 0 评论 -
数据结构与算法学习笔记(二)稀疏数组
稀疏数组的应用场景编写的五子棋程序中,有存盘退出和续上盘的功能。因为该二维数组的很多值是默认值0, 因此记录了很多没有意义的数据.->稀疏数组当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。疏数组的处理方法是:记录数组一共有几行几列,有多少个不同的值把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模比如上面这个67的数组,可以用93的数组代替,第一行分别是原来矩阵的行、列、不同的值的个数以后每行分别记录每一个非零值在原来数组中原创 2020-07-27 21:30:05 · 209 阅读 · 0 评论 -
数据结构与算法学习笔记(一)线性结构和非线性结构
数据结构包括:线性结构和非线性结构。线性结构线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系线性结构有两种不同的存储结构,即顺序存储结构和链式存储结构。顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的(是指元素的存储地址是连续的)链式存储的线性表称为链表,链表中的存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址信息不一定是连续的线性结构常见的有:数组、队列、链表和栈非线性结构非线性结构包括:二维数组,多维数组,广义表,树结构,图结构...原创 2020-07-27 21:11:08 · 261 阅读 · 0 评论