数据结构
夹毛局的程序员
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
35.骑士周游问题马踏棋游戏
弗洛伊德算法弗洛伊德算法(Floyd-Warshall Algorithm),跟克鲁斯卡尔算法一样是为了解决给定加权图中某一个顶点到其他顶点间的最短距离,可以处理有向图或负权的最短路径问题,同时也被用于在计算有向图的传递闭关。该算法已创始人之一,1978年图领奖获得者,斯坦福大学计算机教授罗伯特·弗洛伊德。适用范围:无负权回路即可,边权正负都可以,运行一次算法即可得到任意两点之间的最短路径。优缺点Floyd算法适用于APSP(AllPairsShortestPaths),是一种动态规划算法,稠密图效原创 2020-08-12 17:59:07 · 389 阅读 · 0 评论 -
34.弗洛伊德算法
弗洛伊德算法弗洛伊德算法(Floyd-Warshall Algorithm),跟克鲁斯卡尔算法一样是为了解决给定加权图中某一个顶点到其他顶点间的最短距离,可以处理有向图或负权的最短路径问题,同时也被用于在计算有向图的传递闭关。该算法已创始人之一,1978年图领奖获得者,斯坦福大学计算机教授罗伯特·弗洛伊德。适用范围:无负权回路即可,边权正负都可以,运行一次算法即可得到任意两点之间的最短路径。优缺点Floyd算法适用于APSP(AllPairsShortestPaths),是一种动态规划算法,稠密图效原创 2020-08-12 17:57:36 · 909 阅读 · 0 评论 -
33.迪杰斯特拉算法
迪杰斯特拉算法迪杰斯特拉算法(Dijkstra)是经典的最短路径算法,用于计算一个节点到其他节点的最短路径。他的主要特点以起始点为中心向外层层扩散(广度优先搜索思想BFS),直到扩展到终点为止。迪杰斯特拉算法过程设置出发顶点为v,顶点集合V(v1,v2,v3…vn),v到V中其他顶点的距离构成一个集合Dis,Dis(d1,d2,d3…dn),记录着v到途中其他各个顶点的具体,v到v自身的距离为0,v到v1的距离为di从Dis中选择最小的di移除Dis集合,移除V集合中对应顶点的vi,此时v到vi的原创 2020-08-12 17:55:53 · 220 阅读 · 0 评论 -
32.克鲁斯卡尔算法
克鲁斯卡尔算法克鲁斯卡尔算法(kruskal)跟普里姆算法一样,目的都是求无向图的最小生成树。普里姆算法核心在于一个顶点接一个顶点的找出最短路径,克鲁斯卡算法在于将每一条边进行升序排序,然后通过边进行筛选从而组成最小生成树。实现步骤核心思想在于按权值从小到大排序选择n-1条边,并保证选择边不会构成回路。用到核心的数据结构并查集来判断是否构成回路。将所有的边按权值大小升序排列创建一个数组selectEdges存在选择出来的边循环遍历已经排好序的边,如果该边不构成回路,则添加到selectEdge原创 2020-08-12 17:55:16 · 521 阅读 · 0 评论 -
31.普里姆算法
最小生成树一个有 n 个结点的带权无向图,在满足所有顶点都连接的前提下使得所有的边的权总和最小,即为最小生成树(Minimum Spanning Tree MST)。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。N个顶点,一定有N-1条边包含所有顶点所有顶点都可以直接或间接连接到另外的顶点普里姆算法普里姆算法在找最小生成树时,将顶点分为两类,一类是在查找的过程中已经包含在树中的(假设为 A 类),剩下的是另一类(假设为 B 类)。对于给定的连通网,起始状态全原创 2020-08-12 17:53:42 · 328 阅读 · 0 评论 -
30.贪心算法
贪心算法贪心算法(又称贪婪算法),核心思想在求解问题的时候,总是选择当前情况的最优解。贪心算法不是所有问题都能得到整体最优解,核心在于贪心算法的策略选择,选择的贪心策略需要具备无后效性,即某个状态以前的过程不能影响以后的状态至于当前状态有关。贪心算法总是选择当前情况下的最优选择,而不是从整体最优考虑。贪心算法是做的局部最优选择,最终的结果可能在整体环境下不是最优解,但非常接近最优解。贪心算法也会因为策略不同得到不同的结果。应用场景集合覆盖问题假设存在下面需要付费的广播台,以及广播台信号可以覆盖的地原创 2020-08-07 15:11:10 · 426 阅读 · 0 评论 -
29.kmp算法
KMP算法KMP算法是用来做字符串匹配的,他以他的三个发明者命名,其效率非常高。常见的字符串匹配算法BF(BruteForce)暴力匹配对主串和模式串进行逐个字符匹配,效率很低,每一轮只能将模式串右移一位。BM(Boyer-Moore)算法 核心试想是模式串中不存在的字符一定不匹配,后移KMP算法 核心在于部门匹配表(partial match table),本质也是减少冗余的字符比较核心代码获取部分匹配表 /** * PMT中的值是字符串的前缀集合与后缀集合的交集中最长元素原创 2020-08-07 15:01:50 · 275 阅读 · 0 评论 -
28.动态规划01背包问题
动态规划动态规划 Dynamic Programming,核心思想就是将大问题划分成小问题进行解决,从而一步一步的获得最优解的处理算法动态规划跟分治算法思想类似,但动态规划算法会依赖到上一次计算的结果,每次求解是建立在上一次子阶段的结果基础之上进一步处理,而分治算法分解出来问题往往是独立的动态规划一般可以通过填表的方式进行逐步推进得到最优解0/1背包问题01背包问题是经典的利用动态规划算法求解的一个经典案例有n个物品,他们有各自的重量(w)和价值§,有一个给定容量capacity容量的背包,原创 2020-08-04 16:16:26 · 136 阅读 · 0 评论 -
27.分治算法
分治算法分治算法的核心思想就是将一个规模N的问题拆分为K个规模小的子问题,这些子问题相对嘟咧且与原问题相同或类似,求出所有子问题的解,然后再合并所有子问题的结果即是原问题的解。步骤分解: 将原问题拆分若干的规模较小,容易解决,相对独立性质与原问题相同子问题求解: 直接当子问题递归分解到较小,容易解决的问题,然后得出结果合并:将各个子问题的结果通过某种方法合并得到原问题的解它的一般的算法设计模式如下:Divide-and-Conquer§if |P|≤n0then return(ADHO原创 2020-08-04 16:15:18 · 178 阅读 · 0 评论 -
26.二分查找算法
核心思想:将有序序列二等分,如果目标数比中值小,继续往左边递归二分,再取中值,如果比中值大则往右边递归,一直到中值索引刚好落在目标值上(找到)或者一直二等分到一个元素无法再分割结束(未找到)。二分递归实现 public static int binarySearch(int[] arr, int target, int left, int right) { if (left > right) { return -1; }原创 2020-08-04 16:13:06 · 189 阅读 · 0 评论 -
25.图的遍历广度优先算法和深度优先算法
深度优先算法 Depth First Search DFS深度优先搜索,从初始访问节点触发,当初始访问节点有多个邻接节点的时候,深度优先算法策略就是首先访问第一个邻接节点,然后再以这个节点作为初始节点继续访问他的第一个邻接节点深度优先访问策略优先从纵向深挖,而不是先访问一个节点的所有邻接节点深度优先算法是一个递归过程优先先将一个顶点所有能连接上的边都访问一遍,尽管他不是直接跟顶点连接间接通过其他顶点连接的也能递归访问,只要能通过其他顶点间接连接也会被递归出来深度优先遍历算法步骤访问初始节点原创 2020-08-04 16:11:25 · 214 阅读 · 0 评论 -
24.图的基础介绍
图图是一种数据结构,其中节点可以具有零个或者多个相邻的元素,两个节点之间的连接成为边。节点也可以成为顶点。常用概念顶点 vertex 图中的每一个节点都是一个顶点 通常记做V边 edge 两个顶点之间的连接 通常记做E路径 从一个顶点到另一个顶点经过的边的总和,如果带权则是所有边的权重和无向图 顶点与顶点之间没有方向,即可以从顶点A到顶点B,也可以动B到A有向图 与无向图相反顶点与顶点之间存在明显的方向带权图 边上面带有权值的图称为带权图弧头 弧尾 在有向图中,无箭头端的顶点称为起始点原创 2020-08-04 16:09:49 · 208 阅读 · 0 评论 -
23.B树B+树B星树原理分析
多路查找树二叉树的查询效率非常高,但也存在问题,当二叉树的数据量非常大,节点非常多的时候,因为二叉树要求最多左右两个子节点,会导致二叉树的高度很高。我们一般在构建二叉树的时候会伴随很多IO操作如从文件系统读取获取或者数据库读取数据,过高的二叉树会导致操作效率的低下,如果数据量过于庞大内存也支撑不了。在AVL节点很多的时候,当插入元素之后为保持平衡会频繁的调整节点的位置,导致性能的下降。从而引出了多叉树,允许在一定情况下一个节点可以保存多个数据,一个节点也允许挂多个子节点,这样就大大减少的树的高度,增加的原创 2020-07-31 11:34:26 · 941 阅读 · 0 评论 -
22.平衡二叉树AVL树
平衡二叉树排序二叉树中存在一个问题就是可能会退化成一个链表,当只有左子树或者右子树有节点的时候,此时排序二叉树就像链表一样,但因为排序二叉树在插入查询的时候还要判断左右子树的问题,这样查询的效率反而变低,从而引出了平衡二叉树平衡二叉树又称平衡搜索树(Self-balance Binary Search Tree)又称AVL树,同时保证了查询和添加的效率。首先平衡二叉树是一颗排序二叉树,且它是空树或者他的每一个节点分支的左右两颗子树的高度差值的绝对值小于等于1。平衡二叉树的实现方法主要有红黑树,AVL,替原创 2020-07-30 11:38:10 · 294 阅读 · 0 评论 -
21.排序二叉树BST
二叉排序树二叉排序树(Binary Sort Tree BST)又称二叉查找树(Binary Search Tree BST),二叉树中的一种特殊形式,查询和添加的效率比较高。二叉排序树要求任何一个非叶子节点的左节点的值应该小于等于当前节点,右节点的值应该大于等于当前节点。如果有相同的值,可以挂在左边也可以挂在右边节点添加添加的元素比当前节点小,如果当前节点左节点为空,直接挂上,否则往左递归添加元素比当前元素大或者等于,如果当前节点右节点为空,直接挂上,否则往右递归 /**原创 2020-07-29 11:58:57 · 154 阅读 · 0 评论 -
20.赫夫曼编码的数据解压
赫夫曼编码的数据解压上篇是说了用赫夫曼编码进行数据压缩,现在实现对压缩数据的解压。核心步骤将原来压缩成byte数组的编码转成一个二进制字符串对转成的二进制字符串与赫夫曼码表上的数据进行匹配 从而还原原本数据的byte数组先将原先码表反转 因为先要通过 value 找key对二进制字符串进行遍历 使用指针一直扫描字符串,每扫描到一个字符去码表中匹配,如果匹配到了说明该字符串匹配到了原本的一个byte,加入到一个集合中核心方法 /** * 将压缩之后的赫夫曼编码重新还原成原原创 2020-07-28 15:27:12 · 307 阅读 · 0 评论 -
19.赫夫曼编码和数据压缩
赫夫曼编码赫夫曼编码是一种变长编码方式,在通信中是一种经典的应用。广泛用于文件压缩,压缩率通常在20%~90%之间,主要通过使用的频率在最大化节约字符的存储空间。实现步骤统计各个字符的使用次数,用一个Node节点保存起来,具体data属性为字符对应的byte,weight权重代表他出现的次数根据上述统计构建赫夫曼树根据构建的赫夫曼树约定编码向左路径为0,右路径为1单独创建一个全局的赫夫曼码表Map<byte,String> key为字符对应的byte String是该字符在这个赫夫原创 2020-07-27 17:12:33 · 316 阅读 · 0 评论 -
18.赫夫曼树
赫夫曼树路径和路径长度:表示树从根节点开始到达节点经过的次数,若一颗树根节点为1层,那么第K层的树的路径的长度为K-1权: 赋予每一个节点上面特定的权重值带权路径:带权路径等于节点的权与路径长度的乘积,为带权路径 = 权 * 路径长度树的带权路径长度:为所有叶子节点的带权路径之和记做WPL(weight path length)赫夫曼树huffman-tree或哈夫曼树,又称最优二叉树,如果一颗二叉树的带权路径之和最小,及权值越高的越靠近根节点的树为最优二叉树。核心思想将一个序列从小到大原创 2020-07-27 17:11:07 · 241 阅读 · 0 评论 -
17.java实现堆排序
堆排序堆是一种完全二叉树的数据结构,完全二叉树就是若设二叉树的深度为k,除第 k 层外,其它各层 (1~k-1) 的结点数都达到最大个数,第k 层所有的结点都连续集中在最左边,这就是完全二叉树。大顶堆: 每个节点值都大于或等于其子节点的值 公式 arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]小顶堆: 每个节点值都小于或等于其他节点的值 公式 arr[i] <= arr[2i+1] && arr[i] <=原创 2020-07-27 16:32:39 · 167 阅读 · 0 评论 -
16.顺序存储二叉树和线索化二叉树
顺序存储二叉树顺序存储二叉树是指用一个数组存储的二叉树,一般用于完全二叉树,物理上用数组存储逻辑上是一个树结构。第n个元素的左节点索引2n+1第n个元素的右节点索引2n+2第n个元素的父节点为(n-1)/2n为元素在数组中的索引代码示例class Node { Node left; Node right; int id; Object data; public Node(int id, Object data) { this.dat原创 2020-07-27 11:52:22 · 226 阅读 · 0 评论 -
15.树基本概念和常用术语
树Tree树是一种数据结构,它由n(n>0)个有限节点组成具有层次结构关系的集合,像一颗倒挂的树,根向上,叶子向下。二叉树二叉树是一同特殊的树,二叉树中每一个节点最多只有2个节点。二叉树层次从2层开始,在第i层最多有2^(i-1)个节点 如第二层最多2个节点 第三层最多4个节点高度为k的二叉树 一共最多有2^k-1个节点满二叉树:最后一层的叶子界面是满的,就是满二叉树,满二叉树节点总数为 2^k - 1 k为层数[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接原创 2020-07-24 10:41:42 · 406 阅读 · 0 评论 -
14.Java实现数组链表哈希表
哈希表哈希表又称散列表,是根据关键字key来加速访问的数据结构。通过一个关键字key通过一个映射函数到达表中一个位置访问记录,从而加快查询速度。而映射函数成为散列函数,存储记录的表成为散列表。自实现一个简单哈希表采用数组+链表的形式每一个数组维护了一个链表,链表中保存了具体数据哈希算法采用了简单的取模算法示意图代码示例HashTab 用户直接操作的哈希表NodeLinkedList 哈希表中数组中内部维护的一个链表Node 存储数据的节点 真正保存数据的类HashTab中的增删改原创 2020-07-24 10:37:37 · 384 阅读 · 0 评论 -
13.斐波那契查找
斐波那契查找算法斐波那契数列,又称黄金分割数列,除前2个数之后,后面一个数等于前面2个数之和。如1,1,2,3,5,8,13,21… 定义为F(1)=1 F(2) =1 …F(n) = F(n-1) + F(n-2),当n值越大的时候约接近黄金比例0.618斐波那契查找算法就是在这基础上实现,本质上跟二分查找思想一致,只是在找中值索引的时候使用了斐波那契的思想进行黄金分割。实现步骤根据需求创建一个斐波那契数列根据原数组的长度找到最接近的一个斐波那契数列的长度如果原数组长度小于斐波那契数列要求的原创 2020-07-21 15:27:52 · 912 阅读 · 0 评论 -
12.二分查找和插值查找
二分查找核心思想:将有序序列二等分,如果目标数比中值小,继续往左边递归二分,再取中值,如果比中值大则往右边递归,一直到中值索引刚好落在目标值上(找到)或者一直二等分到一个元素无法再分割结束(未找到)。代码示例这里列出了两个方法一个是返回一个是找到元素索引,一个是返回所有找到元素索引的集合。返回集合的思路也很简单,只需要在找到目标元素之后分别向左和向右循环找值相等的元素集合,需要注意的是在循环的之后要保证索引不越界即可。 /** * 查找多 个数据的二分查找法 *原创 2020-07-21 15:27:18 · 183 阅读 · 0 评论 -
11.归并排序和基数排序
归并排序核心思想:拆分和合并,拆分其实只干了一件事将数组2等份,一直拆分到无法拆分为止,合并在于从最小拆分单元先排序,然后向上合并再排序,最终得到一个有序数组。分支算法采用的递归操作,核心代码在于合并。public class MergeSort { public static void main(String[] args) { int arr[] = {8, 4, 5, 7, 1, 3, 6, 2}; // int[] temp = new int[arr.原创 2020-07-21 15:24:34 · 119 阅读 · 0 评论 -
10.希尔排序和快速排序
希尔排序希尔排序是对直接插入排序的改进,直接插入排序的缺点在于如果从小到大排序,但是最小数在很后面,这样会造成大量的数据移位操作,希尔排序核心思想将数组平均分成2组之后进行直接快速排序,然后一直分组到最后只能分成一组的时候结束,分组的方式是通过步长来进行分组。希尔排序分组的方式使得尽快的让小的数放在前面,大的放在后面,减少移动的次数。 public static void shellSortBySwap(int[] arr) { int temp = 0; // 每原创 2020-07-17 15:58:32 · 824 阅读 · 0 评论 -
9.冒泡排序和选择排序
冒泡排序核心思想是循环length-1次,每次循序找出最大或者最小的一个数,每次比较相邻的两个数,如果大或者小就交换位置,每一次循环可以比较当次最大的一个数。例如 3, 10, -1, 20,8第一次循环指针下移指向 3 3和10比较 不交换 3 10 -1 20 8指针下移指向 10 10>-1 交换 3 -1 10 20 8指针下移指向 10 10<20 不交换 3 -1 10 20 8指针下移指向 20 20>8 交换 3 -1 10 8 20退出第一次循环 找原创 2020-07-16 11:49:38 · 186 阅读 · 0 评论 -
8.时间频度和时间复杂度
度量一个程序算法执行时间的两种方法事后统计法: 直白就是把程序跑一边,统计程序从开始到结束花费的时间。缺点在于需要将程序跑一边,如果越到耗时程序的时候效率不高,而且要求计算机的硬件软件的环境一致,保证运行环境相同才有可信度。事后统计法: 通过分析某一个程序算法具体的时间复杂度来度量一个算法的优劣。时间频度一个算法花费的时间与算法中语句执行数成正比。哪个算法执行的次数越多,则它花费的时间就多。一个算法中语句执行的次数成为时间频度,记做T(n)。例如:计算1-100的总和// 方式1int t原创 2020-07-16 11:23:43 · 2934 阅读 · 0 评论 -
7.递归回溯问题经典案例迷宫问题和八皇后
迷宫问题核心思路在于递归线路选择/** * 约定迷宫的出口是row,column 即右下角的那个点 * 约定数字1为墙,2为走过的路,3为死路,0表示没有走过 */public class MazeDemo { final int x; final int y; int[][] maze; public MazeDemo(int x, int y) { this.x = x; this.y = y; initMaz原创 2020-07-14 15:45:42 · 220 阅读 · 0 评论 -
6.基于stack实现简单的逆波兰计算器
波兰表达式我们常见人类容易理解的计算公式如1+2 (3+2)等属于中缀表达式,这种表达式的特点是如何人们阅读的习惯,但是计算机在处理的时候需要对公式进行运算顺序的处理,不利于计算机的理解,从而计算机学家发明了波兰表达式这种易于计算机理解的表达式。前缀表达式,又称波兰表达式,特点在于运算符在前操作数在后如 - + * 1 2 3 4,计算顺序从右至左,依次将3 2 1 压入stack遇操作符 pop出stack中的1 2 计算 得到 2 重新push到stack中遇+操作符 弹出 stack中原创 2020-07-13 15:24:20 · 280 阅读 · 0 评论 -
5.stack栈基本应用
栈特点FILO先进后出,数据首先被压入push栈顶之上,成为新的栈顶,弹出pop从栈顶中移除一个元素,并将栈顶指针下移一位。使用数组模拟栈class SimpleStack { final int maxSize; int[] data; int top; public SimpleStack(int maxSize) { this.maxSize = maxSize; top = -1; data = new int原创 2020-07-10 17:57:43 · 220 阅读 · 0 评论 -
4.环形链表与约瑟夫问题
环形链表的特点在于链表的最后一个节点的next指向了链表的头节点head数据节点class CircleNode { int order; public CircleNode next; public CircleNode(int order) { this.order = order; } @Override public String toString() { return "Node{" +原创 2020-07-10 11:07:59 · 163 阅读 · 0 评论 -
3.双向链表
双向链表中每个数据节点都有两个指针,分别指向上一个节点和下一个节点。数据节点// 双向链表节点 有2个指针class Node { int order; Object data; public Node pre; public Node next; public Node(int order, Object data) { this.order = order; this.data = data; }原创 2020-07-10 10:04:14 · 124 阅读 · 0 评论 -
2.环形队列的数组实现
环形队列队列是一种特殊的线性表,包含队头,队尾,特性为FIFO (Fisrt In Fisrt Out) 先进先出。环形队列是队列中的一种,目的是为了让空间可以重复使用。核心算法 取模算法(rear/front + i) % maxSize 将指针后移 i 个位置rear 指针后移一位 (rear + 1) % maxSizefront 指针后移一位 (rear + 1) % maxSizeisEmpty 是否为空 rear指针和front指针在同一个位置 front == rearifF原创 2020-07-07 16:08:03 · 185 阅读 · 0 评论 -
1.数据结构-稀疏数组
稀疏数组如果一个数组(或者多维)中有大量的重复元素,可以使用稀疏数组来保存,以达到节约空间的目的。稀疏数组的创建过程稀疏数组的第一行表示数组几行几列(各个维度的长度)最后一位表示有效值个数// 如一个二维数组int[5][5] 其他大部分为默认值0只有3个赋值了// 则稀疏数组第一行为 5 5 3// 如是多维数组如int[5][5][7] 则第一行为 5 5 7 3稀疏数组除第一行之后的行表示了每一个有效数组的坐标和值//例如一个二维数组 arr = int[3][3]// a原创 2020-07-07 10:48:46 · 193 阅读 · 0 评论
分享