程序员必备的几种常用排序算法和搜索算法总结搜索算法知识,虽然还有很多高级算法需要了解,但是基础还是要夯实的。本文将以图文形式介绍以下算法知识。希望大家看完后有所收获:冒泡排序和Itoptimizesselectionsortinsertionsortmergesortquicksortordersearchbinarysearchtext我想对于每个前端工程师来说,最头疼的就是算法问题,但是算法往往是一个衡量一个人编程能力的非常重要的指标。目前,很多主流的框架和库都应用了大量的算法和设计模式。为了让自己的段位更高,只能继续“杀怪”(也就是刷算法),升级成为“最强王者”。其实前端开发这么多年,越来越倾向于精细化开发。许多超级应用(如淘宝、微信)都在追求极致的用户体验。时间就是金钱。这就要求工程师只要能用就不要开发程序。我们经常需要进行更详细的测试(包括单元测试、性能测试等)。以排序为例。对于大规模数据量的排序,使用冒泡排序肯定要被疯狂吐槽,因为冒泡排序性能极差(复杂度为O(n^2))。在实际项目中,我们往往不用冒泡排序,还有更多会用到快速排序或者希尔排序,关于排序算法的性能,我在《前端算法系列》如何将前端代码速度提升60倍有详细介绍,接下来让我们一起学习如何实现几种文章开头常见的排序和搜索算法一、冒泡排序及其优化我们在学习排序算法的时候,最容易掌握的就是冒泡排序,因为实现起来非常简单,但是从运行性能的角度来看,是最差的一个。冒泡排序的思路是比较任意两个相邻的item,如果前者比后者大,则进行交换。为了更方便的展示冒泡的过程分拣和性能测试sting,作者先写了几个工具和方法,动态生成指定数的随机数组,生成元素位置序列。方法,代码如下://生成指定数的随机数组constgenerateArr=(num=10)=>{letarr=[]for(leti=0;i{letpos=[]for(leti=0;iarr[j+1]){//replacement[arr[j],arr[j+1]]=[arr[j+1],arr[j]]}}}returnarr}接下来我们测试它。我们使用generateArr方法生成一个包含60个数组项的数组,动态生成元素坐标://generatecoordinatesconstpos=generateArrPosX(60)//生成一个包含60个数组项的数组constarr=generateArr(60)执行代码后,会生成如下随机节点结构:css部分这里就不介绍了,大家可以自己实现。接下来,我们可以测试我们上面写的冒泡排序。当我们点击排序时,结果如下:可以看到数组已经排好序了,我们可以使用console.time来衡量代码执行所花费的时间。上面的“乞丐版”冒泡排序耗时0.2890625ms。通过深入分析代码,我们可以知道两层。for循环排序导致大量冗余排序。如果我们将内循环减去外循环已经运行的轮数,就可以避免内循环进行不必要的比较,所以我们的代码优化如下://冒泡排序优化版本bubbleSort(arr=[]){letlen=arr.length//针对(leti=0;iarr[j+1]){//替换[arr[j],arr[j+1]]=[arr[j+1],arr[j]]}}}returnarr}优化冒泡排序耗时:0.279052734375ms,比以前稍微好一点,但还是不推荐序列算法。2.选择排序选择排序的思想是在数据结构中找到最小值放在第一位,然后找到第二个最小值放在第二位,以此类推。我们还是按照之前的模式,生成一个60项的数组,如下:选择排序代码如下:selectionSort(arr){letlen=arr.length,indexMinfor(leti=0;iarr[j]){indexMin=j}}if(i!==indexMin){[arr[i],arr[indexMin]]=[arr[indexMin],arr[i]]}}returnarr}点击排序时,结果如下:说明代码运行正常,可以实现排序.控制台耗时为:0.13720703125ms,明显优于冒泡排序性能。3.插入排序插入排序的思想是每次排列一个数组项,假设第一项已经排好序,然后与第二项进行比较,确定第二项的位置,进而确定第三项的位置以此类推,最后将整个数组从小到大排序。代码如下:insertionSort(arr){letlen=arr.length,j,temp;for(leti=1;i0&&arr[j-1]>temp){arr[j]=arr[j-1]j--}arr[j]=temp;}}执行结果如下:控制台打印时间为:0.09912109375ms.4.归并排序归并排序算法的性能优于以上三种,可以在实际项目中投入使用,但实现方法相对复杂。归并排序是一种分而治之的算法,其思想是将原数组分成更小的数组,直到每个小数组只有一个元素,然后将小数组合并成更大的数组,最后成为排序好的大数组实现过程如下图所示:为了实现这个方法,我们需要准备一个合并函数和一个递归函数。具体实现如下://mergesortmergeSortRec(arr){letlen=arr.lengthif(len===1){returnarr}letmid=Math.floor(len/2),left=arr.slice(0,mid),right=arr.slice(mid,len)returnmerge(mergeSortRec(left),mergeSortRec(right))}//合并方法merge(left,right){letresult=[]l=0,r=0;while(l1){index=partition(arr,left,right)if(leftpart){j--}if(i<=j){//替换[arr[i],arr[j]]=[arr[j],arr[i]]i++j--}}returni}7.顺序搜索算法也是我们常用的算法之一,比如我们要找一个用户或者一段数据,无论是在前端还是后端,我们都会用到搜索算法。先介绍一下最简单效率最低的顺序搜索。主要思想是将每个数据结构中的元素与我们要查询的元素进行比较,然后返回指定元素的索引。顺序查找之所以效率低下,是因为每次都从数组头部开始查询,直到找到要查找的值,整体查询不够灵活和动态。顺序搜索代码实现如下:sequentialSearch(arr,item){for(leti=0;iitem){max=mid-1}else{returnmid}}return-1}其实搜索算法有很多种,作者在js中详细介绍了基本搜索算法的实现和170万条数据下的性能测试。参考:学习JavaScript数据结构和算法