数据结构
fan儿
这个作者很懒,什么都没留下…
展开
-
JAVA实现LRU缓存
1. 题目:设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能:(1)set(key,Value):将记录(key,Value)插入该结构(2)gte(key):返回key对应的value值2. 要求:(1)set和get方法的时间复杂度为O(1)。(2)某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的。(3)当缓存的大小超过K时,移除最不经常使用的记录,即set和get最久远的。3. 思路:实现一个双向链表,功能: 增加节点 删除原创 2020-10-26 10:11:31 · 210 阅读 · 1 评论 -
贪心算法(JAVA)
基本介绍贪心算法是指在对问题进行求解的时候,在每一步选择中都采取最好的或者最优(最有利)的选择,从而希望能够导致最好或者最优的算法贪心算法所得到的结果不一定是最优的(有时是最优解)但是都是相对近似(接近)最优解。算法的应用问题:有城市北京、上海、天津、广州、深圳、成都、杭州、大连,有五个电台K1(北京、上海、天津)、K2(广州、北京、深圳)、K3(成都、杭州、上海)、K4(上海、天津)K5(杭州、大连),问如何选择最少的电台数,使得覆盖所有的城市代码实现public class Greed原创 2020-06-03 19:45:39 · 363 阅读 · 0 评论 -
KMP算法及其应用(JAVA)
基本介绍KMP是一个解决模式串在文本串是否出现过,如果出现过,最早出现的位置的经典算法KMP算法利用之前判断过信息,通过一个next数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过next数组找到,前面匹配过的位置,省去大量时间代码实现public class KMPAlogrithm { public static void main(String[] args) { //测试 String str1="BBC ABCDAB ABCDABCD原创 2020-05-31 23:31:05 · 314 阅读 · 0 评论 -
动态规划应用(JAVA)
基本介绍(1)核心思想:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法(2)基本思想:将代求解问题分成若干子问题,先求解子问题,然后从这些子问题的解得到原问题的解(3)与分治算法不同的是,适合用动态规划求解的问题,经分解得到子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,是进行进一步的解)(4)动态规划可以通过填表的方式来逐步推出,得出最优解利用动态规划解决01背包问题代码实现:/** * 动态规划解决背包问题 */public clas原创 2020-05-30 23:48:23 · 175 阅读 · 0 评论 -
分治算法的应用(JAVA)
基本介绍“分而治之”,就是把一个复杂问题分成两个或更多相同或相似的子问题,再把子问题分成更小的子问题…直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。基本步骤1、分解:将原问题分解为若干规模较小,相互独立,与原问题形式相同的子问题2、解决:若子问题规模较小而容易被解决则直接解决,否则递归地解各个子问题3、合并:将各个子问题的解合并为原问题的解利用分治算法实现汉诺塔问题public class DivideAndConquare { public static void原创 2020-05-30 23:33:44 · 324 阅读 · 0 评论 -
二分查找(2)(JAVA实现)
该二分查找采用的是非递归的方式代码实现:public class BinarySearchNoRecur { public static void main(String[] args) { int[] arr={1,3,4,7,9,13,15,17}; int target=9; System.out.println(binarySearchNoRecur(arr,target)); } //二分查找的非递归实现 /*原创 2020-05-30 23:28:16 · 132 阅读 · 0 评论 -
图的深度遍历与广度遍历(JAVA实现)
为什么要有图?(1)线性表局限于一个直接前驱和一个直接后继的关系(2)树也只有一个直接前驱也就是父节点(3)当我们需要表示多对多关系时,就需要用到了图概念:表示方式:(1)二维数组(邻接矩阵)(2)链表表示(邻接表)邻接表:(1)邻接矩阵需要为每个顶点都分配n个边的空间,其实很多边都是不存在,会造成空间的一定的损失(2)邻接表的实现只关心存在的边,不关心不存在的边,因此没有空间浪费,由链表+数组组成。深度优先遍历深度优先遍历(Depth First Search):(1)原创 2020-05-30 23:25:49 · 328 阅读 · 0 评论 -
平衡二叉树(AVL)(JAVA实现)
为什么要有平衡二叉树?因为有的时候,一颗树只有左子树或者右子树有节点,这样像一个单链表,相对于查找就没有优势了。基本介绍:(1)平衡二叉树也叫平衡二叉搜索树,又被称为AVL树,可以保证查询效率(2)具有以下特点:它是一颗空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树情况(一):当rightHeight - leftHeight>1成立,此时不是一颗AVL树,需要进行左旋转步骤:(1)创建一个新节点newNode,值等于当前节点的值(2)把新节点的左原创 2020-05-27 22:49:24 · 139 阅读 · 0 评论 -
二叉排序树(JAVA实现)
基本介绍:BST(Binary Sort Tree),对于二叉排序树的任何非叶子节点,要求左子节点的值比当前节点小,右子节点的值比当前节点的值大注意:如果有相同的值,可以将该节点放在左子节点或右子节点删除节点:1、删除叶子节点(1)先找到要删除的节点 targetNode(2)找到targetNode的父节点parent(3)确定targetNode是parent的左子节点还是右子节点(4)根据前面的情况对应删除左子节点: parent.left=null右子节点:parent.rig原创 2020-05-26 22:35:08 · 140 阅读 · 0 评论 -
赫夫曼编码与解码(JAVA实现)
**作用:**用于压缩文件,是无损压缩步骤:设传输的字符串为:(i like like like java do you like a java)(1)计算各字符出现的次数:d:1 y:1 u:1 j:2 v:2 o:2 I:4 k:4 e:4 i:5 a:5 (空格):9(2)按照上面字符出现的次数,构建一颗赫夫曼树,次数作为权值(3)根据赫夫曼树,给各个字符,规定编码(前缀编码),向左路径为0,向右路径为1(5)按照上述的赫夫曼编码,就可以得到字符串对应的编码**注意:**赫夫曼树根据排原创 2020-05-26 22:21:28 · 175 阅读 · 0 评论 -
赫夫曼树(JAVA实现)
基本介绍:(1)给定n个权值作为n个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称赫夫曼树(哈夫曼树)(2)赫夫曼树是带权路径长度最短的树,权值较大的节点离根比较近重要概念:(1)路径和路径长度:在一颗树中,从一个结点往下可以达到孩子或者孙子节点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从第L层节点的路径长度为L-1(2)结点的权及带权路径长度:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该节点的权,结点的带权原创 2020-05-23 23:31:08 · 174 阅读 · 0 评论 -
堆排序(JAVA实现)
基本介绍:(1)堆排序利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最好,最坏,平均时间复杂度都是O(nlogn),它是不稳定排序。(2)堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;**注意:**没有要求结点的左孩子的值和右孩子的值得大小关系。(3)每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。基本思想:(1)将堆排序序列构造成一个大顶堆(小顶堆)(在数组中操作)(2)此时,整个序列的最大值就是堆顶的根节点(3)将其与末原创 2020-05-23 23:16:40 · 172 阅读 · 0 评论 -
顺序存储二叉树(JAVA实现)
概念:从数据存储来看,数据存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组。要求:在遍历数组时,仍然可以进行前序遍历,中序遍历,后序遍历。代码实现:public class ArrBinaryTreeDemo { public static void main(String[] args) { // TODO 自动生成的方法存根 //创建数组 int[] arr= {1,2,3,4,5,6,7}; //进行前序遍历 BinaryTree原创 2020-05-23 23:08:15 · 191 阅读 · 0 评论 -
二叉树(JAVA实现)
为什么需要树这种数据结构?1、数组存储方式分析:(1)优点:通过下标访问元素,速度快。对于有序数组,还可以使用二分查找提高检索速度。(2)缺点:如果检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低2、链式存储方式的分析:(1)优点:在一定程度上对数组存储方式有优化(如插入一个数值节点,只需要将插入的节点,链接到链表中即可,删除效率也很好)(2)缺点:在进行检索是,效率仍然较低,需要从头开始遍历3、树存储方式的分析:(1)优点:能提高数据存储效率,读取的效率,比如利用二叉排序树,既原创 2020-05-18 23:32:48 · 301 阅读 · 0 评论 -
哈希表(JAVA实现)
基本介绍:哈希表(Hash Table)是根据关键码值(key value)而直接进行访问的数据结构,也就是说它通过关键码值映射到表中一个位置访问记录,以加快查找速度。这个映射函数交散列函数,存放记录的数组叫散列表(哈希表)结构:(1)哈希表=数组+链表(2)哈希表=数组+二叉树代码实现:(数组+链表结构)public class HashTableDemo { public static void main(String[] args) { // TODO 自动生成的方法存根 ha原创 2020-05-17 22:07:01 · 309 阅读 · 0 评论 -
斐波那契查找(JAVA实现)
对F[k-1]-1的理解:(1)F[k]=F[k-1]+F[k-2] F[k]-1=(F[k-1]-1)+(F[k-2]-1)+1说明:只要顺序表长度为F[k]-1,则可以将表分为F[k-1]-1和F[k-1]-1两段,而中间位置为mid=low+F[k-1]-1(2)类似的,每个子段也可以用相同放式分割(3)但顺序表长度n不一定等于F[k]-1,所以需要将原来顺序表长度n增加至F[k]-1,这里K值只要能使F[k]-1恰好大于等于n即可代码实现:public class Fibona.原创 2020-05-16 23:52:36 · 322 阅读 · 1 评论 -
插值查找(JAVA实现)
原理:1、插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找2、将折半查找中的求mid公式修改,low表示左边索引left,high表示右边索引right,findVal表示查找值(1)二分法:mid=(low+high)/2=low+(high-low)/2(2)自适应(可以理解为一条线上的占比)mid=low+(findVal-arr[low])*(arr[high]-arr[low])/(high-low);代码实现:public class insertValS原创 2020-05-16 21:36:51 · 197 阅读 · 0 评论 -
二分查找(JAVA实现)
注意:二分查找法只能用于有序的数组思路分析:1、首先确定该数组中间的下标 mid=(left+right)/22、然后让需要查找的数findVal和arr[mid]进行比较(1)如果findVal>arr[mid],则向数的右边进行递归查找(2)如果findVal<arr[mid],则向数的左边进行递归查找(3)findVal==arr[mid]就返回什么时候结束递归?(1)找到就结束(2)当left>right代码实现:public class halfSear原创 2020-05-14 22:19:28 · 146 阅读 · 0 评论 -
基数排序(JAVA实现)
基本介绍:(1)通过键值得各个位的值,将要排序的元素分配至一些桶中,达到排序的作用(2)基数排序法是属于稳定性的排序,基数排序法是效率高的稳定排序法(3)基数排序是桶排序的扩展稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]前面,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的,否则称为不稳定的。图解:代码实现:public class RadixSort原创 2020-05-14 20:37:36 · 1123 阅读 · 4 评论 -
归并排序(JAVA实现)
基本原理:代码实现:public class MergeSort { public static void main(String[] args) { // TODO 自动生成的方法存根 //测试数组 int[] arr= {8,4,5,7,1,3,6,2}; int[] temp=new int[arr.length]; mergeSort(arr, 0, arr.length-1, temp); System.out.println("归并排序后="+Arrays.to原创 2020-05-13 22:34:01 · 86 阅读 · 0 评论 -
快速排序(JAVA实现)
基本思想:通过一趟排序将要排序的数据分割成独立的两个部分,其中一部分所有数据都比另一部分的所有数据都要小,然后在按此方法对这两部分数据分别进行快速排序。整个排序过程可以递归进行,以此达到整个数据变成有序序列。代码实现:public class QuickSort { public static void main(String[] args) { // TODO 自动生成的方法存根 //定义一个测试的数组 int[] arr= {-9,78,0,23,-567,70,-1,900,45原创 2020-05-13 21:17:48 · 75 阅读 · 0 评论 -
希尔排序(JAVA实现)
基本思想:把记录按下标的一定增量分组,对每组使用直接插入排序算法排序,随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成1组,算法便被终止。示例:代码实现:public class ShellSort { public static void main(String[] args) { // TODO 自动生成的方法存根 //定义一个测试数组 int[] arr= {8,9,1,7,2,3,5,4,6,0}; int gap=arr.length; /原创 2020-05-12 22:30:28 · 170 阅读 · 0 评论 -
插入排序(JAVA实现)
基本思想:把n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序列表中的适当位置,使之成为新的有序表。代码实现:public class InsertedSort { public static void main(String[] args) { // TODO 自动生成的方法存根 //定义一个测试的数组 int[] arr= {3,6,原创 2020-05-11 22:19:52 · 343 阅读 · 0 评论 -
选择排序(JAVA实现)
排序思想:第一次从arr[0]到arr[n-1]中选取最小值,与arr[0]交换。第二次从arr[1]到arr[n-1]中选取最小值,与arr[1]交换…第i次从arr[i-1]到arr[n-1]中选取最小值,与arr[i-1]交换…第n-1次从arr[n-2]到arr[n-1]中选取最小值,与arr[i-2]交换。总共通过n-1次,得到一个按排序从小到大排列的有序序列。排序规则:1、选择排序一共有 数组的大小-1轮排序2、每轮排序,又是一个循环,循环规则:(1)先假定当前数是最小值(2)然后和原创 2020-05-11 21:12:04 · 4258 阅读 · 6 评论 -
冒泡排序(JAVA实现)
基本思想:通过对待排序序列从前向后(从下标较小的元素开始),一次比较相邻元素的值,若发现逆序则交换,使值较大的元素,从前移向后部。排序规则:(1)一共进行 数组的大小-1次的循环(2)每一趟排序的次数在逐渐的减少(3)如果发现在某趟排序中,没有发生交换,可以提前结束冒泡排序(优化)代码实现:public class BubbleSort { public static void main(String[] args) { // TODO 自动生成的方法存根 //定义一个进行排序的数原创 2020-05-11 20:36:40 · 90 阅读 · 0 评论 -
算法的时间复杂度
概念:度量一个程序执行时间的方法。通过分析某个算法的时间复杂度来判断哪个算法更优秀。时间频度:一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中执行次数多,它花费时间就多。一个算法中语句执行次数称之为语句频度或则时间频度,记为T(n)特点:当n趋于无穷大时,常数项,系数项,低次项可以忽略。时间复杂度:(1)一般情况下,算法中基本操作语句的重复执行次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋于无穷大时,T(n)/f(n)的极限值不等于0的常数,则称f(原创 2020-05-09 22:29:03 · 182 阅读 · 0 评论 -
递归回溯算法实现八皇后问题(JAVA实现)
八皇后问题思路分析:(1)第一个皇后放第一行第一列(2)第二个皇后放在第二行第一列,然后判断是否ok,如果不ok,则继续放在第二列,第三列…依次都放完,找到一个合适的位置(3)继续第三个皇后,还是第一列,第二列…知道八个皇后也能放在一个不冲突的位置,算是找到一个合适的位置(4)当得到一个正解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到(5)然后回头继续第一个皇后放到第二列,后面继续循环执行1,2,3,4步骤。代码实现:public class Que原创 2020-05-09 21:11:29 · 174 阅读 · 0 评论 -
使用递归实现简单迷宫问题(JAVA实现)
递归:**概念:**方法自己调用自己,每次调用的时候传入不同的变量,递归有助于解决复杂问题,同时还让代码变得简洁。需要遵守的规则:(1)执行一个方法时,就创建一个新的受保护的独立空间(栈空间)(2)方法的局部变量是独立的,不会相互影响(3)如果方法中使用的是引用类型变量(如数组),就会共享该引用类型的数据(4)递归必须向退出递归的条件逼近,否则就无限递归,出现StackOverflowError(栈内存溢出)(5)当一个方法执行完毕,或者遇见return,就会返回,遵守谁调用就将结果返回给谁,原创 2020-05-08 21:18:30 · 531 阅读 · 0 评论 -
中缀表达式到后缀表达式(JAVA实现)
中缀表达式转后缀表达式的思路分析:1、初始化两个栈:运算符栈s1和存储中间结果的栈s22、从左到右扫描中缀表达式3、遇到操作数时,将其压入是s24、遇到运算符时,比较其与s1栈顶运算符优先级比较(1)、如果s1为空或则栈运算符为左括号,则直接将此运算符入栈s1(2)、否则,优先级比栈顶运算符的高,也将直接将运算符压入s1(3)、否则,将s1栈顶的运算符弹出并压入s2中,再次转到4(1...原创 2020-05-08 08:48:11 · 237 阅读 · 0 评论 -
使用堆栈完成计算表达式(JAVA实现)
题目描述:对"6+3*3-3"进行计算思路分析:(0)创建两个栈,一个用于存放数字,一个用于存放运算符(1)通过一个index值(索引),来遍历表达式(2)如果是一个数字,就直接进入堆栈(3)如果是一个运算符的话:①如果当前运算符栈为空,则直接进入堆栈②如果当前运算符栈不为空,则与之前的那个运算符进行优先级比较。如果优先级小于或者等于之前的那一个运算符,就需要从数栈中pop出两个数字...原创 2020-05-06 21:49:10 · 682 阅读 · 0 评论 -
单向环形链表解决约瑟夫问题(JAVA实现)
单向环形链表:结构示意图:构建单向环形链表思路:(1)先创建一个节点first指向该节点,并形成环形链表(2)后面我们每创建一个新的节点,就把该节点加入到已有环形链表中即可如图所示:步骤:1、curboy.next=boy2、boy.next=first3、curboy=boy遍历环形链表:(1)先让一个辅助指针(变量)curBoy,指向first节点(2)然后通过一个...原创 2020-05-04 22:24:41 · 219 阅读 · 0 评论 -
双向链表(JAVA实现)
双向链表与单链表的对比:1、单向链表查找只能是一个方向,双向链表可以向前或者向后查找2、单向链表不能自我删除,需要靠辅助节点**(即需要通过找到要删除的节点的前一个节点,通过该节点进行删除的操作,而双向链表只需找到要删除的节点就行了)**。双向链表可以自我删除双向链表示意图分析(代码实现原理):temp为辅助节点(因为头节点不可动)1、遍历:方式与单链表一致,但是是双向的,可以向前,也...原创 2020-05-01 23:40:51 · 931 阅读 · 0 评论 -
单链表(JAVA实现)
概念:链表是有序的列表,在内存中存储如下:小结:(1)链表是以节点的方式来存储,是链式存储(2)每个节点包含data域、next域(用于指向下一个节点)(3)链表每个节点不一定是连续存储(4)链表分带头节点和不带头节点链表(根据需求确定)单链表(带头节点)逻辑结构示意图:单链表的创建:(不考虑节点顺序)示意图:步骤:1、先创建一个Head节点,作用就是表示单链表的头2、...原创 2020-04-28 00:07:03 · 346 阅读 · 1 评论 -
从队列到环形队列(二)Java实现
数组模拟环形队列:思路:1、front变量的含义做一个调整:front指向队列的第一个元素,即front初始值为0。2、rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置,希望空出一个空间作为约定,rear的初始值为0。3、当队列满时:(rear+1)%maxSize=front为什么要%maxSize?因为如果不%maxSize ,会发生索引越界的问题。4、当...原创 2020-04-23 16:18:37 · 111 阅读 · 0 评论 -
从队列到环形队列(JAVA实现)(一)
队列:概念:队列是一个有序列表,可以用数组或者链表实现。遵循先入先出的原则。(先存入队列的数据,先取出,后存入的数据后取出) 例: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200423160214184.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10...原创 2020-04-23 16:05:36 · 166 阅读 · 0 评论 -
稀疏数组
二维数组转稀疏数组public static void main(String[] args) { // TODO 自动生成的方法存根 //创建原始二维数组 //原始数组为11*11的棋盘,0表示无子,1表示黑子,2表示蓝子 int[][] Array1=new int[11][11]; Array1[1][2]=1; Array1[2][3]=2;...原创 2020-04-21 23:27:23 · 73 阅读 · 0 评论 -
数组实现堆栈(JAVA)
首先明确堆栈的特点是:先进后出,后进先出本文使用数组实现堆栈:public class Stack { private int[] stack; //定义一个长整型的数组 private int top; //记录位置 private int size; //数组的大小 public Stack(int Size) { //设定数组的大小 this.siz...原创 2020-05-05 22:33:39 · 699 阅读 · 0 评论