Java数据结构和算法
以尚硅谷的视频所做的笔记,博客。仅供大家学习
码ming
这个作者很懒,什么都没留下…
展开
-
常用算法——马踏棋盘算法(骑士周游问题)
马踏棋盘算法介绍和游戏演示马踏棋盘算法也被称为骑士周游问题将马随机放在国际象棋的8×8 棋盘Board[0~7][0~7]的某个方格中,马按走棋规则(马走日字)进行移动。要求每个方格只进入一次,走遍棋盘上全部64 个方格游戏演示: http://www.4399.com/flash/146267_2.htm马踏棋盘游戏代码实现马踏棋盘问题(骑士周游问题)实际上是图的深度优先搜索(DFS)的应用。如果使用回溯(就是深度优先搜索)来解决,假如马儿踏了53 个点,如图:走到了第53 个,坐标(1转载 2020-11-19 22:20:55 · 331 阅读 · 0 评论 -
Java数据结构和算法笔记总结
第 1章 数据结构和算法概述数据结构和算法的关系数据 data 结构(structure)是一门研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构可以编写出更加漂亮,更加有效率的代码。要学习好数据结构就要多多考虑如何将生活中遇到的问题,用程序去实现解决.程序 = 数据结构 + 算法数据结构是算法的基础, 换言之,想要学好算法,需要把数据结构学到位。数据结构和算法的应用修路问题 => 最小生成树(加权值)【数据结构】+ 普利姆算法最短路径问题 => 图+弗洛原创 2020-11-19 13:06:18 · 1376 阅读 · 0 评论 -
常用算法——弗洛伊德(Floyd)算法(最短路径问题)
弗洛伊德(Floyd)算法介绍和Dijkstra 算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法。该算法名称以创始人之一、1978 年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名弗洛伊德算法(Floyd)计算图中各个顶点之间的最短路径迪杰斯特拉算法用于计算图中某一个顶点到其他顶点的最短路径。弗洛伊德算法VS 迪杰斯特拉算法:迪杰斯特拉算法通过选定的被访问顶点,求出从出发访问顶点到其他顶点的最短路径;弗洛伊德算法中每一个顶点都是出发访问点,所以原创 2020-11-18 18:19:45 · 26994 阅读 · 2 评论 -
常用算法——迪杰斯特拉(Dijkstra)算法(最短路径问题)
迪杰斯特拉(Dijkstra)算法介绍迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。迪杰斯特拉(Dijkstra)算法过程设置出发顶点为v,顶点集合V{v1,v2,vi…},v 到V 中各顶点的距离构成距离集合Dis,Dis{d1,d2,di…},Dis集合记录着v 到图中各顶点的距离(到自身可以看作0,v 到vi 距离对应为di)从Dis 中选择值最小的di 并移出原创 2020-11-12 17:53:06 · 1483 阅读 · 3 评论 -
常用算法——克鲁斯卡尔(Kruskal)算法(公交站问题,最小生成树问题 )
克鲁斯卡尔算法介绍克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法。基本思想:按照权值从小到大的顺序选择n-1 条边,并保证这n-1 条边不构成回路具体做法:首先构造一个只含n 个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中,并使森林中不产生回路,直至森林变成一棵树为止克鲁斯卡尔算法图解说明以城市公交站问题来图解说明克鲁斯卡尔算法的原理和步骤:代码实现import java.util.Arrays;public class KruskalCase原创 2020-11-10 16:48:06 · 3875 阅读 · 0 评论 -
常用算法——普里姆(prim)算法( 修路问题,最小生成树问题 )
最小生成树修路问题本质就是就是最小生成树问题, 先介绍一下最小生成树(Minimum Cost Spanning Tree),简称MST。给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树N 个顶点,一定有N-1 条边包含全部顶点N-1 条边都在图中举例说明(如图:)求最小生成树的算法主要是普里姆算法和克鲁斯卡尔算法普里姆算法介绍普利姆(Prim)算法求最小生成树,也就是在包含n 个顶点的连通图中,找出只有(n-1)条边包含所有n 个顶点的连原创 2020-11-08 23:10:34 · 933 阅读 · 1 评论 -
常用算法——贪心算法(集合覆盖问题)
贪心算法介绍贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法贪婪算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果贪心算法最佳应用-集合覆盖假设存在如下表的需要付费的广播台,以及广播台信号可以覆盖的地区。如何选择最少的广播台,让所有的地区都可以接收到信号思路分析: 如何找出覆盖所有地区的广播台的集合呢,使用穷举法实现,列出每个可能的广播台的集合,这被称为原创 2020-11-08 21:02:31 · 527 阅读 · 0 评论 -
常用算法——KMP算法(字符串匹配问题,暴力匹配算法)
KMP 算法介绍KMP 是一个解决模式串在文本串是否出现过,如果出现过,最早出现的位置的经典算法Knuth-Morris-Pratt 字符串查找算法,简称为“KMP 算法”,常用于在一个文本串S 内查找一个模式串P 的出现位置,这个算法由Donald Knuth、Vaughan Pratt、James H. Morris 三人于1977 年联合发表,故取这3 人的姓氏命名此算法.KMP 方法算法就利用之前判断过信息,通过一个next 数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过nex原创 2020-11-08 16:57:36 · 348 阅读 · 0 评论 -
常用算法——动态规划算法(背包问题)
动态规划算法介绍动态规划(Dynamic Programming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。( 即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)动态规划可以通过填表的方式来逐步推进,得到最优解.动态规划算法最佳实践-原创 2020-11-07 23:32:21 · 1105 阅读 · 0 评论 -
常用算法——分治算法(汉诺塔)
分治算法介绍分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……分治算法可以求解的一些经典问题 二分搜索 大整数乘法 棋盘覆盖 合并排序 快速排序 线性时间选择 最接近点对问题 循环赛日程表 汉诺塔分治算法的基本步骤原创 2020-11-07 14:59:30 · 2396 阅读 · 0 评论 -
图(,图的创建,深度优先遍历,广度优先遍历)
图基本介绍为什么要有图前面我们学了线性表和树线性表局限于一个直接前驱和一个直接后继的关系树也只能有一个直接前驱也就是父节点当我们需要表示多对多的关系时, 这里我们就用到了图。图的举例说明图是一种**数据结构**,其中结点可以具有零个或多个相邻元素。两个结点之间的连接称为边。结点也可以称为顶点。如图:图的常用概念顶点(vertex)边(edge)路径无向图(下图有向图带权图图的表示方式图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)。邻接矩阵原创 2020-11-07 11:50:15 · 1050 阅读 · 0 评论 -
多路查找树(了解一下)
二叉树的问题分析二叉树的操作效率较高,但是也存在问题, 请看下面的二叉树二叉树需要加载到内存的,如果二叉树的节点少,没有什么问题,但是如果二叉树的节点很多(比如1 亿), 就存在如下问题:问题1:在构建二叉树时,需要多次进行i/o 操作(海量数据存在数据库或文件中),节点海量,构建二叉树时,速度有影响问题2:节点海量,也会造成二叉树的高度很大,会降低操作速度.多叉树在二叉树中,每个节点有数据项,最多有两个子节点。如果允许每个节点可以有更多的数据项和更多的子节点,就是多叉树(multiwa原创 2020-11-05 16:57:30 · 174 阅读 · 0 评论 -
树结构实际应用(平衡二叉树,AVL 树)
看一个案例(说明二叉排序树可能的问题)给你一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在. 左边BST 存在的问题分析:左子树全部为空,从形式上看,更像一个单链表.插入速度没有影响查询速度明显降低(因为需要依次比较), 不能发挥BST的优势,因为每次还需要比较左子树,其查询速度比单链表还慢解决方案-平衡二叉树(AVL)基本介绍平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL 树,原创 2020-11-05 00:34:04 · 823 阅读 · 0 评论 -
树结构实际应用(二叉排序树,BST,二叉搜索树)
11.4 二叉排序树11.4.1 先看一个需求给你一个数列(7, 3, 10, 12, 5, 1, 9),要求能够高效的完成对数据的查询和添加11.4.2 解决方案分析使用数组数组未排序, 优点:直接在数组尾添加,速度快。缺点:查找速度慢. [示意图]数组排序,优点:可以使用二分查找,查找速度快,缺点:为了保证数组有序,在添加新数据时,找到插入位置后,后面的数据需整体移动,速度慢。[示意图] 使用链式存储-链表不管链表是否有序,查找速度都慢,添加数据速度比数组快,不需要数据整体移动。[示原创 2020-11-04 17:44:28 · 472 阅读 · 0 评论 -
树结构实际应用(赫夫曼树编码)
import java.util.ArrayList;import java.util.Collections;import java.util.List;public class HuffmanTree { public static void main(String[] args) { int arr[] = { 13, 7, 8, 3, 29, 6, 1 }; Node root = createHuffmanTree(arr); // 测试一把 preOrder(roo原创 2020-11-03 22:22:04 · 458 阅读 · 0 评论 -
树结构实际应用(堆排序,赫夫曼树,哈夫曼树)
堆排序堆排序基本介绍堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 注意: 没有要求结点的左孩子的值和右孩子的值的大小关系。每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆大顶堆举例说明我们对堆中的结点按层进行编号,映射到数组中就是下面这个样子:大顶堆特点:arr[i] >= arr原创 2020-11-02 00:10:37 · 623 阅读 · 0 评论 -
二叉树(顺序存储二叉树,线索化二叉树)
顺序存储二叉树顺序存储二叉树的概念a.基本说明从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组,看下面的示意图。b. 要求:右图的二叉树的结点,要求以数组的方式来存放arr : [1, 2, 3, 4, 5, 6, 6]要求在遍历数组arr 时,仍然可以以前序遍历,中序遍历和后序遍历的方式完成结点的遍历c.顺序存储二叉树的特点:顺序二叉树通常只考虑完全二叉树第n 个元素的左子节点为2 * n + 1第n 个元素的右子节点为2 * n原创 2020-10-29 23:59:10 · 1287 阅读 · 0 评论 -
二叉树——增删改查
二叉树为什么需要树这种数据结构数组存储方式的分析优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低[示意图]画出操作示意图:链式存储方式的分析优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可,删除效率也很好)。缺点:在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历) 【示意图】操作示意图:树存储方式的分析能提高数原创 2020-10-26 00:17:55 · 1045 阅读 · 0 评论 -
哈希表(散列表)-增删改查
哈希表哈希表的基本介绍散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。有些数据没必要一直访问数据库 因为每次查数据库,数据库太慢了,对数据库压力太大了 所以把数据放入哈希表 ,用哈希表取不到再去数据库取,把数据库经常取的数据放入哈希表google 公司的一个上机题:有一个公司,当有新的员工来报道时,要求将该原创 2020-10-25 11:01:26 · 1746 阅读 · 0 评论 -
Java查找算法(线性查找,二分查找递归和非递归,插值查找,斐波那契查找算法)
查找算法查找算法介绍在java 中,我们常用的查找有四种:顺序(线性)查找二分查找/折半查找插值查找斐波那契查找线性查找算法有一个数列: {1,8, 10, 89, 1000, 1234} ,判断数列中是否包含此名称【顺序查找】要求: 如果找到了,就提示找到,并给出下标值。代码实现:public class SeqSearch { public static void main(String[] args) { int arr[] = { 1, 9, 11, -1, 34,原创 2020-10-24 18:09:14 · 355 阅读 · 0 评论 -
Java排序算法-基数排序
基数排序基数排序(桶排序)介绍:基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法基数排序(Radix Sort)是桶排序的扩展基数排序是1887 年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。基数原创 2020-10-20 22:52:26 · 235 阅读 · 0 评论 -
排序算法高阶(希尔排序,快速排序,归并排序)
希尔排序简单插入排序存在的问题我们看简单的插入排序可能存在的问题.数组arr = {2,3,4,5,6,1} 这时需要插入的数1(最小), 这样的过程是:{2,3,4,5,6,6}{2,3,4,5,5,6}{2,3,4,4,5,6}{2,3,3,4,5,6}{2,2,3,4,5,6}{1,2,3,4,5,6}结论: 当需要插入的数是较小的数时,后移的次数明显增多,对效率有影响.希尔排序法介绍希尔排序是希尔(Donald Shell)于1959 年提出的一种排序算法。希尔排序也是一种插原创 2020-10-20 15:59:34 · 518 阅读 · 2 评论 -
排序算法基础(冒泡排序,选择排序,插入排序)
排序算法的介绍原创 2020-10-15 00:41:36 · 612 阅读 · 0 评论 -
算法复杂度(时间频度,时间复杂度介绍计算,空间复杂度)
时间复杂度原创 2020-10-11 20:47:13 · 5330 阅读 · 0 评论 -
递归(递归介绍,迷宫问题,八皇后问题)
递归的概念简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。递归调用机制打印问题阶乘问题使用图解方式说明了递归的调用机制public class RecursionTest {public static void main(String[] args) {// TODO Auto-generated method stub//通过打印问题,回顾递归调用机制//test(4);int res = factorial原创 2020-10-08 15:10:37 · 211 阅读 · 0 评论 -
栈第二部分(前缀、中缀、后缀表达式(逆波兰表达式))
前缀、中缀、后缀表达式(逆波兰表达式)前缀表达式(波兰表达式)前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前举例说明: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6前缀表达式的计算机求值从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果例如: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4原创 2020-10-08 00:59:07 · 318 阅读 · 1 评论 -
栈第一部分(数组模拟栈,单链表模拟栈,应用)
栈的介绍栈的英文为(stack)栈是一个先入后出(FILO-First In Last Out)的有序列表。栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除图解方式说明出栈(pop)和入栈(push)的概念栈的应用场原创 2020-10-07 23:48:35 · 216 阅读 · 0 评论 -
链表 第二部分:双向链表,单向的环形链表,约瑟夫问题,Josephu
双向链表循环链表原创 2020-10-06 23:54:06 · 276 阅读 · 2 评论 -
链表 第一部分:单向链表增删改反转合并等
链表链表(Linked List)介绍链表是有序的列表,但是它在内存中是存储如下:小结上图:链表是以节点的方式来存储,是链式存储每个节点包含 data 域:存数据的, next 域:指向下一个节点.如图:发现链表的各个节点不一定是连续存储.链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定单链表逻辑结构单链表(带头结点) 逻辑结构示意图如下:单链表的应用实例使用带head头的单向链表实现 –水浒英雄排行榜管理完成对英雄人物的增删改查操作, 注: 删除和修改,查找原创 2020-10-06 19:37:13 · 477 阅读 · 0 评论 -
稀疏数组和队列(顺序队列和循环队列)
稀疏 sparsearray 数组基本介绍当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。稀疏数组的处理方法是:记录数组一共有几行几列,有多少个不同的值把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模为什么要使用稀疏数组?稀疏数组可以简单的看作为是压缩,在开发中也会使用到。比如将数据序列化到磁盘上,减少数据量,在IO过程中提高效率等等。由于稀疏矩阵中存在大量的“空”值,占据了大量的存储空间,而真正有用的数据却少之又少,且在计算原创 2020-10-05 14:42:42 · 422 阅读 · 0 评论