二分查找,分治算法,动态规划算法,KMP算法,贪心算法,prim算法,Kruskal算法,Dijistra算法,Floyd算法,马踏棋盘算法程序员常用的10个算法你我皆牛马

此篇写的是非递归算法,递归的在之前的查找算法中写过了。

1.1算法的适用条件

二分查找只适用于从有序的数列中进行查找(比如数字和字母等),将数列排序后在查找。

1.2算法的效率:

实例:使用二分查找的非递归形式对数组{138101167100}进行查找

publicclassBinarySearchNoRecur{publicstaticvoidmain(String[]args){//测试int[]arr={1,3,8,10,11,67,100};intindex=binarySearch(arr,100);System.out.println("index="+index);//}//二分查找的非递归实现/****@paramarr待查找的数组,arr是升序排序*@paramtarget需要查找的数*@return返回对应下标,-1表示没有找到*/publicstaticintbinarySearch(int[]arr,inttarget){intleft=0;intright=arr.length-1;while(left<=right){//说明继续查找intmid=(left+right)/2;if(arr[mid]==target){returnmid;}elseif(arr[mid]>target){right=mid-1;//需要向左边查找}else{left=mid+1;//需要向右边查找}}return-1;}}

2.分治算法

2.1分治算法介绍

1)分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题.....直到最后子问题可以简单的直接求解,原问题的姐即子问题的解的合并。这个技巧是很多高效算法的基础,入排序算法(快排,归并排序),傅里叶变换(快速傅里叶变换)...

2)分治算法可以求解的一些经典问题

2.2分治算法的基本步骤

分治算法在每一层递归上都有三个步骤

1)分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题

2)解决:若干问题规模较小而容易被解决则直接解,否则递归地解决各个子问题

3)合并:将各个子问题的解合并为原问题的解。

2.3分治(Divide-andConquer(P))算法设置模式:

2.4分治算法的实践:汉诺塔(有ABC三个塔)

2.5思路:

1)如果是一个盘,A->C

如果我们有n>=2个盘,我们总是可以看做是两个盘:1.最下面的盘2.上面的盘

(1)先把最上面的盘A->B

(2)把下面的一个盘A->C

(3)把B塔的所有盘从B->C

2.6代码实现:

publicclassHanoitower{publicstaticvoidmain(String[]args){hanoiTower(10,'A','B','C');}//汉诺塔的移动的方法//使用分治算法publicstaticvoidhanoiTower(intnum,chara,charb,charc){//如果只有一个盘if(num==1){System.out.println("第1个盘从"+a+"->"+c);}else{//如果我们有n>=2情况,我们总是可以看做是两个盘1.最下边的一个盘2.上面的所有盘//1.先把最上面的所有盘A->B,移动过程会使用到chanoiTower(num-1,a,c,b);//2.把最下边的盘A->CSystem.out.println("第"+num+"个盘从"+a+"->"+c);//3.把B塔的所有盘从B->C,移动过程使用到a塔hanoiTower(num-1,b,a,c);}}}

3.动态规划算法

应用场景-背包问题

3.1动态规划算法介绍:

1)动态规划算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法

2)动态规划算法与分治算法类似,其思想也是将待求问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

3)与分治法不同的是,适合于动态规划求解的问题,经分解得到的子问题往往不是相互独立的。(即下一个子阶段的求解是建立在上一个子阶段的解的基础上进行进一步的求解)

4)动态规划可以通过填表的方式来逐步推进,得到最优解。

3.2完全背包与01背包

完全背包指的是:每种物品都有无线件可以使用;01背包只能每件物品取一个。

3.3思路与图解:

3.4代码实现:

4.KMP算法

4.1暴力匹配算法:

4.1.1代码实现

publicclassViolenceMatch{publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstub//测试暴力匹配算法Stringstr1="硅硅谷尚硅谷你尚硅尚硅谷你尚硅谷你尚硅你好";Stringstr2="尚硅谷你尚硅你~";intindex=violenceMatch(str1,str2);System.out.println("index="+index);}//暴力匹配算法实现publicstaticintviolenceMatch(Stringstr1,Stringstr2){char[]s1=str1.toCharArray();char[]s2=str2.toCharArray();ints1Len=s1.length;ints2Len=s2.length;inti=0;//i索引指向s1intj=0;//j索引指向s2while(i

4.2.1KMP算法介绍:

1)KMP算法是一个解决模式串在文本串是否出现过,如果出现过,最早出现的位置的经典算法。

2)Knuth-Morrirs-Pratt字符串查找算法,简称为“KMP算法”,常用于在一个文本串S内查找一个模式串P的出现位置,这个算法有DonaldKnuth,VaughanPratt,JamesH.Morris三人于1977年联合发表,故取这三个人名命名此算法。

4.2.2KMP算法的应用

4.2.3思路与图解分析:

举例来说,有一个字符串Str1=“BBCABCDABABCDABCDABDE”,判断,里面是否包含另一个字符串Str2=“ABCDABD”?

1.首先,用Str1的第一个字符和Str2的第一个字符去比较,不符合,关键词向后移动一位

2.重复第一步,还是不符合,再后移

3.一直重复,直到Str1有一个字符与Str2的第一个字符符合为止

4.接着比较字符串和搜索词的下一个字符,还是符合。

5.遇到Str1有一个字符与Str2对应的字符不符合。

6.这时候,想到的是继续遍历Str1的下一个字符,重复第1步。(其实是很不明智的,因为此时BCD已经比较过了,没有必要再做重复的工作,一个基本事实是,当空格与D不匹配时,你其实知道前面六个字符是”ABCDAB”。KMP算法的想法是,设法利用这个已知信息,不要把”搜索位置”移回已经比较过的位置,继续把它向后移,这样就提高了效率。)

7.怎么做到把刚刚重复的步骤省略掉?可以对Str2计算出一张《部分匹配表》,这张表的产生在后面介绍

8.已知空格与D不匹配时,前面六个字符”ABCDAB”是匹配的。查表可知,最后一个匹配字符B对应的”部分匹配值”为2,因此按照下面的公式算出向后移动的位数:

移动位数=已匹配的字符数-对应的部分匹配值

因为6-2等于4,所以将搜索词向后移动4位。

9.因为空格与C不匹配,搜索词还要继续往后移。这时,已匹配的字符数为2(”AB”),对应的”部分匹配值”为0。所以,移动位数=2-0,结果为2,于是将搜索词向后移2位。

10.因为空格与A不匹配,继续后移一位。

11.逐位比较,直到发现C与D不匹配。于是,移动位数=6-2,继续将搜索词向后移动4位。

12.逐位比较,直到搜索词的最后一位,发现完全匹配,于是搜索完成。如果还要继续搜索(即找出全部匹配),移动位数=7-0,再将搜索词向后移动7位,这里就不再重复了。

13.介绍《部分匹配表》怎么产生的

先介绍前缀,后缀是什么

“部分匹配值”就是”前缀”和”后缀”的最长的共有元素的长度。以”ABCDABD”为例,

-”A”的前缀和后缀都为空集,共有元素的长度为0;

-”AB”的前缀为[A],后缀为[B],共有元素的长度为0;

-”ABC”的前缀为[A,AB],后缀为[BC,C],共有元素的长度0;

-”ABCD”的前缀为[A,AB,ABC],后缀为[BCD,CD,D],共有元素的长度为0;

-”ABCDA”的前缀为[A,AB,ABC,ABCD],后缀为[BCDA,CDA,DA,A],共有元素为”A”,长度为1;

-”ABCDAB”的前缀为[A,AB,ABC,ABCD,ABCDA],后缀为[BCDAB,CDAB,DAB,AB,B],共有元素为”AB”,长度为2;

-”ABCDABD”的前缀为[A,AB,ABC,ABCD,ABCDA,ABCDAB],后缀为[BCDABD,CDABD,DABD,ABD,BD,D],共有元素的长度为0。

14.”部分匹配”的实质是,有时候,字符串头部和尾部会有重复。比如,”ABCDAB”之中有两个”AB”,那么它的”部分匹配值”就是2(”AB”的长度)。搜索词移动的时候,第一个”AB”向后移动4位(字符串长度-部分匹配值),就可以来到第二个”AB”的位置。

到此KMP算法思想分析完毕!

4.2.4代码实现:

关键是创建部分匹配表,当匹配出现不相等时不要回到原来的后一位,而是回到部分匹配表的后一位(匹配表字符中前一位和后一位相同时,部分匹配表加1)

charAt()方法用于返回指定索引处的字符。索引范围为从0到length()-1。

难点:部分匹配表没有匹配到时:

5.贪心算法

5.1贪心算法介绍

1)贪心算法是指对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法

2)贪心算法得到的结果不一定是最优的结果(有时候是最优解),但是都是相对近似(接近)最优解的结果

5.2实践

5.3思路分析

使用贪心算法可以快速计算准备的值,使用贪心算法,则可以得到非常接近的解,并且效率高。选择策略上,因为需要覆盖地区全部地区的最小集合:

1)遍历所有的广播电台,找到一个覆盖了最多的地区的电台(此电台可能包含一些已经覆盖的电台)

2)将这些电台加入到一个集合中,想方法吧该电台覆盖的地区在下次比较时去掉。

3)重复第一步直到覆盖了全部地区

5.4图解

5.5代码实现:

6.普里姆算法(prim)

6.1算法的实例

6.2算法介绍

6.3图解:

6.4代码实现:

7.克鲁斯卡尔算法

7.1算法实例:

7.2算法介绍

1)克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法。

2)基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路

3)具体做法:首先构造一个只含n个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中,并使森林中不产生回路,直至森林变成一棵树为止

7.3图解

第1步:将边加入R中。边的权值最小,因此将它加入到最小生成树结果R中。第2步:将边加入R中。上一步操作之后,边的权值最小,因此将它加入到最小生成树结果R中。第3步:将边加入R中。上一步操作之后,边的权值最小,因此将它加入到最小生成树结果R中。第4步:将边加入R中。上一步操作之后,边的权值最小,但会和已有的边构成回路;因此,跳过边。同理,跳过边。将边加入到最小生成树结果R中。第5步:将边加入R中。上一步操作之后,边的权值最小,因此将它加入到最小生成树结果R中。第6步:将边加入R中。上一步操作之后,边的权值最小,但会和已有的边构成回路;因此,跳过边。同理,跳过边。将边加入到最小生成树结果R中。

此时,最小生成树构造完成!它包括的边依次是:

根据前面介绍的克鲁斯卡尔算法的基本思想和做法,我们能够了解到,克鲁斯卡尔算法重点需要解决的以下两个问题:问题一对图的所有边按照权值大小进行排序。问题二将边添加到最小生成树中时,怎么样判断是否形成了回路。

问题一很好解决,采用排序算法进行排序即可。

问题二,处理方式是:记录顶点在"最小生成树"中的终点,顶点的终点是"在最小生成树中与它连通的最大顶点"。然后每次需要将一条边添加到最小生存树时,判断该边的两个顶点的终点是否重合,重合的话则会构成回路。

在将加入到最小生成树R中之后,这几条边的顶点就都有了终点:

(01)C的终点是F。(02)D的终点是F。(03)E的终点是F。(04)F的终点是F。

关于终点的说明:

1)就是将所有顶点按照从小到大的顺序排列好之后;某个顶点的终点就是"与它连通的最大顶点"。

因此,接下来,虽然是权值最小的边。但是C和E的终点都是F,即它们的终点相同,因此,将加入最小生成树的话,会形成回路。这就是判断回路的方式。也就是说,我们加入的边的两个顶点不能都指向同一个终点,否则将构成回路

7.4代码实现:

8.迪杰斯特拉(Dijkstra)算法

8.1算法实例

8.2算法介绍

迪杰斯特拉算法是典型的最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层层扩展(广度优先思想),直到拓展到终点为止。

8.3图解

8.4代码实现:

9.1算法介绍:

9.2算法分析与图解

1)设置顶点vi到顶点vk的最短路径已知为Lik顶点vk到vj的最短路径已知为Lkj,顶点vidaovj的路径为Lij,则vi到vj的最短路径为:min((Lik+Lkj),Lij),vk的取值为图中所有顶点,则可获得vi到vj的最短路径

2)至于vi到vj的最短路径Lik或者vk到vj的最短路径Lkj,是以同样的方式获得

THE END
1.十种常见典型算法算法有哪些那么又是哪10个计算机算法造就了我们今天的生活呢?请看下面的表单,排名不分先后: 1.归并排序(MERGE SORT),快速排序(QUICK SORT)和堆积排序(HEAP SORT) 哪个排序算法效率最高?这要看情况。这也就是我把这3种算法放在一起讲的原因,可能你更常用其中一种,不过它们各有千秋。 https://blog.csdn.net/darkhorsefly/article/details/134222961
2.10大计算机经典算法「建议收藏」腾讯云开发者社区BFPRT算法解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分析,BFPRT可以保证在最坏情况下仍为线性时间复杂度。该算法的思想与快速排序思想相似,当然,为使得算法在最坏情况下,依然能达到o(n)的时间复杂度,五位算法作者做了精妙的处理。 https://cloud.tencent.com/developer/article/2089934
3.数据挖掘的10大算法我用大白话讲清楚了,新手一看就懂数据挖掘主要分为分类算法,聚类算法和关联规则三大类,这三类基本上涵盖了目前商业市场对算法的所有需求。而这三类里又包含许多经典算法。市面上很多关于数据挖掘算法的介绍深奥难懂,今天就给大家用简单的大白话来介绍数据挖掘十大经典算法原理,帮助大家快速理解。算法分类 连接分析:PageRank 关联分析:Apriori 分类算法http://baijiahao.baidu.com/s?id=1669165676284257223&wfr=spider&for=pc
4.普通物理学(一)课程教学大纲简谐振动的描述、动力学方程、能量,同方向简谐振动的合成,相互垂直的两个简谐振动的合成,阻尼振动、受迫振动。 2.教学要点 使学生掌握简谐振动的余弦表达式,旋转矢量、相位等概念。掌握无阻尼自由振动的周期、频率、能量等概念,掌握同方向同频率简谐振动的合成,理解李萨如图形,了解阻尼振动、受迫振动。 https://physics.suda.edu.cn/6f/8f/c1873a28559/page.htm
5.数学的论文优秀(15篇)3)注重经典算法的数学软件的实现和改进 由于实际问题的特殊性导致数学模型没有固定的模式,这就要求既要熟练掌握一般数学软件和算法的实现,又要善于改进和总结,使得现有的算法和程序能够通过修正来解决实际问题,这对于学生能力的培养不可或缺。只有不断的学习和总结,才有数学素养的培养和创新能力的提高。 https://www.yjbys.com/biyelunwen/fanwen/shuxue/734624.html
6.《三位数乘两位数》教案(精选15篇)教材第5、6页,想想做做第5~10题 教学目标: 同过练习,使学生进一步掌握、规范末尾有0和中间有0的三位数乘两位数的简便笔算方法。 探索乘数、积的变化规律,进一步明白末尾有0乘法的口算依据。 教学重点: 末尾有0的三位数乘两位数的笔算 教学过程: 一、举例昨天学生作业中的几种典型错误:(竖式略) https://www.ruiwen.com/jiaoan/7431605.html
7.计算机网络与通信之局域网51CTO博客以太网交换机是一种即插即用设备,其内部的帧交换表是通过自学习算法自动地逐渐建立起来的; 支持不同的传输速率和工作模式; 低交换延迟–基于硬件交换技术; 支持虚拟局域网服务。 独占传输媒体的带宽而无碰撞地传输数据 对于普通 10 Mb/s 的共享式以太网,若共有 N 个用户,则每个用户占有的平均带宽只有总带宽(10https://blog.51cto.com/u_16011718/6127981
8.小学一年级数学人教版下册教案生1:我能用小棒摆出自己的算法:先摆出1捆零2根小棒,再从1捆中拿掉8根,把剩下的2根与原来的2根合起来是4根,所以12-8=4。 生2:我能把自己的算法画出来:先在左边画10个圆圈,右边画2个圆圈,表示12,然后从左边的10个圆圈中划掉8个,剩下的2个与右边的2个合起来是4个,即12-8=4。 https://www.unjs.com/jiaoan/shuxue/20220802201517_5383426.html
9.文案必读:创意100招上卷举例:我有一个朋友 / 同学 / 同事 比喻:你比如说 / 这就好像 段子搞:不一定非要段子,你怎样给孩子讲故事、和闺蜜怎样打闹、和兄弟怎样喝酒吹牛,就怎样写。因为文字会自然沾染你的情绪的,你情绪冷,文字就冷,你情绪热,文字就热。 11. 咒语 https://www.digitaling.com/articles/33865.html
10.生命宇宙以及任何事情的终极答案《终极算法》的作者佩德罗?多明戈斯教授有一个假设: 所有知识,无论是过去的、现在的还是未来的,都有可能通过单个通用学习算法来从数据中获得。 多明戈斯将该学习算法称为“终极算法”。 他认为,如果这种算法成为可能,它的发明将成为人类最伟大的科学成就之一。实际上,终极算法是我们最不愿意发明的东西,因为一旦对其https://36kr.com/p/1722788823041.html
11.10个经典的C语言面试基础算法及代码算法是一个程序和软件的灵魂,作为一名优秀的程序员,只有对一些基础的算法有着全面的掌握,才会在设计程序和编写代码的过程中显得得心应手。本文是近百个C语言算法系列的第二篇,包括了经典的Fibonacci数列、简易计算器、回文检查、质数检查等算法。也许他们能在你的毕业设计或者面试中派上用场。 1、计算Fibonacci数列 https://www.imooc.com/article/2775
12.统计学权威盘点过去50年最重要的统计学思想,因果推理bootstrap等他们认为,过去半个世纪中最重要的统计思想是:反事实因果推理,基于bootstrapping(自助抽样法)和基于模拟的推理,超参数化模型和正则化,多层模型,泛型计算算法(generic computation algorithms),自适应决策分析,鲁棒推理和探索性数据分析(未按时间顺序,排序不分先后)。 https://www.thepaper.cn/newsDetail_forward_12835098
13.2020年深度学习算法工程师面经(微软阿里商汤滴滴华为简单分为深度学习、机器学习基础、图像处理基础、数学基础、算法基础、程序设计语言、模型部署、HR面试以及与我本人简历相关的目标检测、属性识别、Kaggle及天池的比赛、创新想法等几个部分介绍。可能开始会有重叠或者分类不恰当,后面会逐渐更新完善。其中第一篇先介绍到HR面试,第二篇介绍个人相关的项目和比赛部分。https://maimai.cn/article/detail?fid=1514590373&efid=Oph3033j5Qs70xHZdz0sGA