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

学习JavaScript中的算法复杂性_0

时间:2023-03-16 13:07:28 科技观察

在本文中,我们将探讨“二次”和“nlog(n)”等术语在算法中的含义。在下面的例子中,我将引用这两个数组,一个有5个元素,另一个有50个元素。我还使用JavaScript中方便的性能API来衡量执行时间的差异。constsmArr=[5,3,2,35,2];constbigArr=[5,3,2,35,2,5,3,2,35,2,5,3,2,35,2,5,3,2,35,2,5,3,2,35,2,5,3,2,35,2,5,3,2,35,2,5,3,2,35,2,5,3,2,35,2,5,3,2,35,2];什么是大O表示法?大O表示法是一种表示计算任务难度随着数据集增加而整体增加的方法。虽然还有其他符号,但通常大O符号是最常用的,因为它着眼于最坏的情况,更容易量化和考虑。最坏情况意味着完成任务所需的操作次数最多;如果你能在不到一秒钟的时间内解开立方体,你就不能说你只转了一次就做得最好了。这在你深入了解算法时非常有用,因为你可以在理解这种关系的同时编写代码,你可以看到时间都花在了哪里。随着你对大O表示法的了解越来越多,你可能会在下图中看到不同的变化。我们希望保持尽可能低的复杂性,最好避免超过O(n)。O(1)这是最理想的情况,无论有多少项,无论是一还是一百万,完成的时间量都将保持不变。大多数执行单个操作的操作都是O(1)。将数据写入数组、获取特定索引处的项目、添加子元素等都将花费相同的时间,而不管数组的长度如何。consta1=performance.now();smArr.push(27);consta2=performance.now();console.log(`Time:${a2-a1}`);//小于1毫秒constb1=performance.now();bigArr.push(27);constb2=performance.now();console.log(`Time:${b2-b1}`);//小于1MillisecondO(n)默认情况下,所有循环都是线性增长的,因为有一个-数据大小与完成所需时间之间的一对一关系。因此,如果您有1,000个数组项,则需要1,000倍的时间。consta1=performance.now();smArr.forEach(item=>console.log(item));consta2=performance.now();console.log(`Time:${a2-a1}`);//3毫秒constb1=performance.now();bigArr.forEach(item=>console.log(item));constb2=performance.now();console.log(`Time:${b2-b1}`);//13MillisecondsO(n^2)指数增长是我们都掉入的陷阱。您是否需要为数组中的每个项目找到匹配对?将循环放在循环中是将1000项数组变成百万次操作搜索的好方法,这将使您的浏览器变得无响应。在两个单独的循环中执行2,000次操作比使用双层嵌套循环执行100万次操作要好。consta1=performance.now();smArr.forEach(()=>{arr2.forEach(item=>console.log(item));});consta2=performance.now();console.log(`时间:${a2-a1}`);//8毫秒constb1=performance.now();bigArr.forEach(()=>{arr2.forEach(item=>console.log(item));});constb2=performance.now();console.log(`Time:${b2-b1}`);//307MillisecondsO(logn)我认为对数增长的一个更好的比喻是想象在字典单词中查找类似“符号”的东西。您不是逐个搜索词,而是首先找到“N”部分,然后是“OPQ”页面,然后按字母顺序搜索列表,直到找到匹配项。使用这种“分而治之”的方法,查找内容的时间仍然会随着字典的大小而变化,但与O(n)相去甚远。因为它在不查看大部分数据的情况下增量搜索更具体的部分,搜索一千项可能只需要不到10次操作,而一百万项可能需要不到20次操作,这使您的效率最大化。在这个例子中,我们可以做一个简单的快速排序。constsort=arr=>{if(arr.length<2)returnarr;letpivot=arr[0];letleft=[];letright=[];for(leti=1,total=arr.length;i{letnum=n;if(n===0)return1for(leti=0;i