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

从二叉堆的进阶到堆排序和优先级队列,前端高手都是这么学的...

时间:2023-03-14 17:05:00 科技观察

1.二叉堆的分类二叉堆根据根的大小可以分为大根堆和小根堆排序。在大根堆是一棵完全二叉树的前提下,其节点值大于其左右子节点的值,称为大根堆。在大根堆中,根节点是所有堆节点中的最大值。在小根堆是一棵完全二叉树的前提下,其节点值小于其左右子节点的值,称为小根堆。在小根堆中,根节点是所有堆节点中值最小的。2、二叉堆的存储上面说明了二叉堆其实就是一棵完整的二叉树,那么数据满足一定的特征,那么在编程中应该如何存储这些数据呢?这些数据之间满足什么关系?1.使用数组结构存储二叉堆在编程中,我们会将二叉堆存储在一个数组中。以上述最大堆为例,数组中存储的结构如下:2、二叉堆中的父子节点满足什么样的关系?既然数据会存储到数组中,那么就必须知道父子节点的关系,即:(1)知道父节点的索引就必须找到对应的子节点;(2)在知道子节点父节点的索引的情况下找到对应的子节点;下面的二叉堆,将其根节点的索引设为0,然后依次递增:已知节点的索引为i,则其左右子节点的索引为:左节点索引=2*i+1右节点索引=左节点索引+1已知一个节点的索引为i,其父节点索引为:parentnode=parseInt((i-1)/2)3.堆的基本操作遇到二进制时heap,我们应该学习如何构建一个大根堆(smallrootheap),这次涉及到加减堆的过程,我们先从加减堆开始,这样我们就可以很顺利的理解整个二进制堆施工过程。(注:下面的例子以Dagenheap为例)//注:这里封装了数组中交换元素的方法//数组中的数据交换functionswap(arr,i,j){lettemp=arr[i];arr[i]=arr[j];arr[j]=temp;}1.添加堆的过程其实就是向堆中添加一个新元素,然后维护堆结构。就是在数组的末尾添加一个元素,然后通过不断向上浮动调整为二叉堆结构的过程。//functionheapInsert(arr,index){//比较当前位置和它的父位置,如果大于它的父位置,交换并移动索引到它的父位置for循环,否则跳过//结束条件是小于其父位置或到达根节点while(index>0&&arr[index]>arr[parseInt((index-1)/2)]){swap(arr,index,parseInt((index-1)/2));index=parseInt((index-1)/2);}returnarr;}有了添加堆的过程,我们就可以轻松创建一个二叉堆,如下图://创建二叉堆函数createBigTopHeap(arr){for(leti=0;iarr[largest]?索引:最大;//if(index===largest){break;//如果最大的值的索引和传入的索引相同,则值到达指定位置,直接结束循环if(index===largest){break;}//交换,改变索引及其左子节点swap(arr,index,largest);指数=最大;左=2*索引+1;}返回arr;}constarr=[1,5,9,10,8,12];console.log(createBigTopHeap(arr));//交换heapTop数据和lastposition数据swap(arr,0,arr.length-1);//通过下沉获取新的heap结果console.log(heapify(arr,0,arr.length-1));41.叉堆的用途由于二叉堆可以高效的找到最大值和最小值,所以可以用来进行堆排序和构建优先级队列1.堆排序堆排序是一种常见的排序算法,整个堆排序过程如下:让数组成为一个大根堆。将最后一个位置与堆顶交换。然后最大值在最后,剩下的部分heapify,然后重新调整成一个大的rootpile,把heap的top位置和这部分的last位置交换。如此反复直到减法完成,那么调整终于完成,整个数组排序完毕(升序)。functionheapSort(arr){if(arr===null||arr.length===0){return[];}//首先创建一个大的根堆for(leti=0;i0){//重新进入大顶堆heapify(arr,0,size);//交换swap(arr,0,--size);}返回arr;}constarr=[1,5,9,10,8,12];控制台日志(堆排序(arr));//[1,5,8,9,10,122.优先级队列普通队列是一种高级的出数据结构,元素在队尾追加,从队头删除。在优先级队列中,元素被赋予优先级。访问元素时,首先删除具有最高优先级的元素。优先级队列具有最高级别的先出(先进先出)行为特征。通常使用堆数据结构实现。优先队列的插入优先队列中元素的插入就是上面的heapInsert过程,通过向数组尾部添加元素,然后通过浮动的方式将内容插入到合适的位置。优先队列中元素的删除优先队列中元素的删除是将根节点的元素与最后一个元素进行交换,然后将交换的根节点下沉,调整到合适的位置,重构二叉堆。