先吐槽,最近面试真的好难!前端面试的源码部分和算法部分的题越来越多。上个月的四次面试,我两次被问到优先级队列的数据结构;幸好React源码的scheduler部分对小顶堆有一定的了解,有些地方比较模糊,现在简单说一下堆的数据结构,以及如何用JS;前端和优先队列。如果你看过React源码的Scheduler部分,应该对timerQueue延迟队列和taskQueue可执行队列有印象。它们都使用了小顶堆的优先级队列数据结构的实现,具体可以看《重学React之为什么需要Scheduler》。在Scheduler部分,这两个队列主要实现调度后的任务优先级排序(时间维度);优先队列和堆优先队列顾名思义就是一个队列,队列有一个从头出队,从尾入队的原则;而优先队列每次出队列都是最大的(大顶堆)或者最小的(小顶堆),所以优先队列其实就是一个堆。堆是一种近似完全二叉树的数据结构。堆可以看作是一个数组。堆实际上是由一棵完全二叉树的结构维护的一维数组。根据排序方式的不同,可以分为大顶堆和小顶堆。大顶堆:每个节点的值都大于或等于其左右子节点的值小顶堆:每个节点的值都小于或等于其左右子节点的值如果将上面堆中的数组数据映射到数组中,然后这样//bigtoppile[50,45,40,20,25,35,30,10,15]//smalltoppile[10,20,15,25,50,30,40,35,45]因此,我们可以根据上面的堆节点值和数组中的下标得到如下两个公式:arr[i]>=arr[2i+1]&&arr[i]>=arr[2i+2]小顶堆:arr[i]<=arr[2i+1]&&arr[i]<=arr[2i+2]如何创建堆?如果我们现在有一个无序的纯数字数组,我们将如何对它进行堆排序?假设我们现在有一个无序数组`[3,7,16,10,21,23]`并且我们需要对它进行堆排序(大顶堆),那么我们需要做什么呢?我们需要从最后一个叶子节点开始,从下往上调整;Q:如何找到最后一个叶子节点?A:因为我们使用一维数组来存储堆中的数据,所以我们可以取数组的长度+1/2取一个整数-1,假设我们的数组名为array,就可以套用最后分页的公式childnode=(array.length+1)%2-1**当前节点的值与左子树节点的值比较,如果当前节点小于左子树的值,则交换当前节点和左子树;交换后检查左子树是否满足大顶堆的性质,如果不满足则重新调整子树结构;****然后比较当前节点的值和右子树节点的值。如果当前节点小于右子树的值,交换当前节点和右子树;然后重新调整子树结构;**当不需要交换调整时,会建立大顶堆constcreateHeap=(arr,)=>{constlength=arr.length//如果数组长度为0或1,直接返回不改变数组(不需要比较)if(length<=1)returnarr//通过下标遍历数组for(let我=1;我<长度;i++){while(i){//通过传入的数组下标获取父节点数组下标并比较替换constparentIndex=Math.floor((i-1)/2)//如果索引值对应当前数组下标大于父节点索引值对应的值,则替换//如果需要创建小顶堆,则arr[i]
