当前位置: 首页 > 科技观察

程序员必须知道的10个基本实用算法及其解释

时间:2023-03-21 10:24:54 科技观察

算法一:快速排序算法快速排序是由TonyHall开发的一种排序算法。平均而言,对n项进行排序需要O(nlogn)次比较。在最坏的情况下需要进行O(n2)次比较,但这并不常见。事实上,快速排序通常比其他OO(nlogn)算法快得多,因为它的内部循环可以在大多数体系结构上有效地实现。快速排序使用分而治之的策略将一个列表分成两个子列表。算法步骤:1.从序列中选取一个元素,称为“枢轴”(pivot),2.对序列重新排序,所有小于枢轴值的元素都放在枢轴前面,所有大于枢轴值的元素都放在放置在枢轴的前面。后面(相同的数字可以去任何一边)。此分区退出后,基准测试位于序列的中间。这称为分区操作。3递归排序小于参考值的元素的子数组和大于参考值的元素的子数组。递归的第一种情况是序列的大小为零或一,即一直排好序。虽然一直在递归,但是这个算法总会退出,因为在每次迭代(iteration)中,它至少会把一个元素放到它最好的位置。算法二:堆排序算法堆排序(Heapsort)是指利用堆的数据结构设计的一种排序算法。堆叠是一种近似完全二叉树的结构,同时满足堆叠的性质:即子节点的键值或索引总是小于(或大于)其父节点。堆排序的平均时间复杂度是O(nlogn)。算法步骤:创建一个堆H[0..n-1]并交换堆头(***值)和堆尾3.将堆的大小减1,调用shift_down(0),目的是把新的数组顶部的数据调整到对应的位置4.重复步骤2,直到堆的大小为1算法3:归并排序归并排序(Mergesort,台湾译:归并排序)是一种有效的排序基于合并操作的算法。该算法是分而治之的一个非常典型的应用。算法步骤:1.申请空间,使其大小为两个排序序列之和,该空间用于存放合并后的序列2.设置两个指针,初始位置分别为两个排序序列的起始位置3.比较两个指针指向的元素,选择一个比较小的元素放入合并空间,将指针移动到下一个位置4.重复步骤3,直到某个指针到达序列的末尾5.将restoftheothersequence所有元素直接复制到合并序列的末尾算法4:二分搜索算法二分搜索算法是一种在有序数组中寻找特定元素的搜索算法。搜索过程从数组的中间元素开始。如果中间元素恰好是要查找的元素,查找过程结束;如果特定元素大于或小于中间元素,则搜索大于或小于中间元素的数组的一半,并从中间元素开始比较。如果在某一步数组为空,则表示找不到。这种搜索算法每次比较都会将搜索范围缩小一半。半搜索每次将搜索区域减半,时间复??杂度为Ο(logn)。算法5:BFPRT(LinearSearchAlgorithm)BFPRT算法解决的问题很经典,就是从n个元素的序列中选出第k大(第k小)的元素。通过巧妙的分析,BFPRT可以保证在最坏情况下仍然具有线性时间复杂度。这个算法的思路和快排的思路类似。当然,为了让算法在最坏情况下仍然达到o(n)的时间复杂度,五位算法作者都做了精巧的处理。算法步骤:1.将n个元素分成5个一组,分成n/5(上界)个组。2、取出每组的中位数,任意排序,如插入排序。3.递归调用选择算法,在上一步中找到所有中位数的中位数,设置为x,设置为在中位数为偶数的情况下选择较小的那个。4、用x划分数组,将小于等于x的数设为k,将大于x的数设为n-k。5.如果i==k,返回x;如果ik,递归地在大于x的元素中寻找第i-k个最小的元素。终止条件:当n=1时,返回第i个元素。算法6:DFS(Depth-First-Search)深度优先搜索是一种搜索算法。它沿着树的深度遍历树的节点,尽可能深入地搜索树的分支。探索完节点v的所有边后,搜索将回溯到找到节点v的边的起始节点。这个过程一直持续到找到所有从源节点可达的节点。如果还有未发现的节点,则选择其中一个作为源节点,重复上述过程,重复整个过程,直到访问完所有节点。DFS是一种盲目搜索。深度优先搜索是图论中的经典算法。使用深度优先搜索算法可以生成目标图对应的拓扑排序表。使用拓扑排序表可以很容易地解决很多相关的图论问题,比如最优路径问题等等。通常使用堆数据结构来辅助实现DFS算法。深度优先遍历图算法步骤:1.访问顶点v;2、依次从v的未访问过的相邻点开始,对图进行深度优先遍历;直到图中所有具有v路径的顶点都被访问;3.如果此时图中还有未访问过的顶点,则从未访问过的顶点开始,再次进行深度优先遍历,直到图中所有顶点都被访问过。上面的描述可能比较抽象。例如:DFS访问图中某个起始顶点v后,从v开始访问它的任意一个相邻顶点w1;顶点w2;然后从w2开始,进行类似的访问,...等等,直到到达所有相邻顶点都被访问过的顶点u。然后,退一步,回到上次刚访问过的顶点,看看是否还有其他相邻的顶点没有访问过。如果有,则访问这个顶点,然后从这个顶点开始执行类似上面的访问;如果没有,返回一步搜索。重复上述过程,直到连通图中的所有顶点都被访问过。#p#算法七:BFS(Breadth-First-Search)广度优先搜索(Breadth-First-Search),是一种图搜索算法。简单的说,BFS从根节点开始,沿着树(graph)的宽度遍历树(graph)的节点。如果访问了所有节点,则算法终止。BFS也是一种盲目搜索。一般使用队列数据结构来辅助实现BFS算法。算法步骤:1.先将根节点放入队列。2.从队列中取出第一个节点并检查它是否是目标。如果找到目标,则结束搜索并返回结果。否则,将其所有尚未检查的直接子项排入队列。3.如果队列为空,则说明整个地图都检查过了——即地图中没有要搜索的目标。结束搜索并返回“找不到目标”。4.重复步骤2。算法8:Dijkstra算法Dijkstra算法(Dijkstra'salgorithm)由荷兰计算机科学家EzgerDijkstra提出。Dijkstra算法采用广度优先搜索解决非负权有向图的单源最短路径问题,算法最终得到一棵最短路径树。该算法常用于路由算法或作为其他图算法的子模块。该算法的输入包括加权有向图G和G中的源顶点S。我们用V表示G中所有顶点的集合。图中的每条边是由两个顶点形成的有序元素对。(u,v)表示从顶点u到v存在一条路径。我们用E表示G中所有边的集合,边的权重由权重函数w定义:E→[0,∞].因此,w(u,v)是从顶点u到顶点v的非负权重。边的权重可以认为是两个顶点之间的距离。任意两点之间路径的权重是路径上所有边的权重之和。鉴于V中有顶点s和t,Dijkstra算法可以找到从s到t的最佳加权路径(例如,最短路径)。该算法还可以找到从顶点s到图中任何其他顶点的最短路径。对于没有负权重的有向图,Dijkstra算法是已知最快的单源最短路径算法。算法步骤:1.初始阶S={V0},T={其他顶点},若T中顶点对应的距离值存在,则d(V0,Vi)为<上的距离V0,Vi>arc如果权值不存在,则d(V0,Vi)为∞2。选择一个与T的距离值最小且不在S中的顶点W,加入到S3中。对于其他T中的顶点的距离值修改:如果加入W作为中间顶点,则缩短V0到Vi的距离,然后修改距离,重复上面的2、3步,直到S包含所有顶点,即即,W=Vi。算法9:动态规划算法动态规划(Dynamicprogramming)是数学、计算机科学和经济学中使用的一种方法,通过将原始问题分解为相对简单的子问题来解决复杂问题。动态规划通常适用于具有重叠子问题和最优子结构属性的问题,并且动态规划方法通常比朴素解决方案花费的时间少得多。动态规划背后的基本思想非常简单。粗略地说,要解决给定的问题,我们需要解决它的不同部分(即子问题),然后组合子问题的解决方案以获得原始问题的解决方案。通常很多子问题都非常相似,所以动态规划方法尽量对每个子问题只求解一次,从而减少计算量:一旦给定的子问题的解已经计算出来,就被记忆存储起来,这样下次需要同样的子问题求解时直接查表。当重复子问题的数量随着输入的大小呈指数增长时,这种方法特别有用。动态规划最经典的问题就是背包问题。算法步骤:1.***子结构属性。如果问题的最优解所包含的子问题的解也是最优的,我们就说这个问题具有最优子结构性质(即满足最优化原理)。***子结构的性质为动态规划算法解决问题提供了重要线索。2.子问题的重叠性。子问题的重叠性是指当使用递归算法自上而下求解问题时,每次产生的子问题并不一定都是新问题,有些子问题会重复计算很多次。动态规划算法利用了这个子问题的重叠性,每个子问题只计算一次,然后将其计算结果保存在一个表中。只需查看结果并获得高效率。算法10:朴素贝叶斯分类算法朴素贝叶斯分类算法是一种基于贝叶斯定理的简单概率分类算法。贝叶斯分类的基础是概率推理,即在各种条件是否存在不确定,只知道发生概率的情况下,如何完成推理和决策任务。概率推理与确定性推理相反。朴素贝叶斯分类器基于独立假设,即假设样本的每个特征与其他特征不相关。朴素贝叶斯分类器依赖于准确的自然概率模型,可以在监督学习样本集上取得非常好的分类结果。在许多实际应用中,朴素贝叶斯模型参数是使用最佳似然估计方法来估计的,换句话说,朴素贝叶斯模型无需使用贝叶斯概率或任何贝叶斯模型即可工作。尽管有这些幼稚的想法和简单化的假设,朴素贝叶斯分类器仍然可以在许多复杂的现实世界情况下取得相当好的结果。原文来自:cricode