JavaScrip通过堆实现针对对象的PriorityQueue

本文将通过最大堆实现优先队列,入队复杂度lg(n),出队复杂度lg(n)

step1:实现最大堆

大堆顶定义,每个二叉树的节点都大于左右子节点

class MaxHeap{

    //构造方法
    constructor(key) {
        this._tree=[]   //初始化数组保存数据
        this._key=key   //设置排序字段key名
    }

    //往队列里添加一个元素,复杂度O(ln(n))
    add(e){
        this._tree.push(e)  //添加对象到队列末尾
        this._adaptUp(this._tree.length-1)  //自底向上调整最大堆
    }

    //获得队首元素值,复杂度O(1)
    getFront(){
        return this._tree[0]  //返回最大堆顶元素
    }

    //获取队首元素值,并弹出队列,复杂度O(ln(n))
    extractMax(){
        //交换队尾和和队首元素,并提取队尾元素,避免队列整体移位
        let tmp=this._tree[0]
        this._tree[0]=this._tree[this._tree.length-1]
        this._tree[this._tree.length-1]=tmp
        let  _max=this._tree.pop()
        this._adaptDown(0)   //自顶向下调整最大堆
        return _max
    }

    //获得队列长度
    getSize(){
        return this._tree.length
    }

    //清空队列
    clear(){
        this._tree.clear()
    }

    //获得左节点id
    _leftChild(idx){
        return idx*2+1
    }

    //获得右节点id
    _rightChild(idx){
        return idx*2+2
    }

    //获得父节点id,“|0”可以对前边的小数取整
    _parent(idx){
        return (idx-1)/2|0
    }

    //交换队列中两个元素
    _swap(idx1,idx2){
        let  tmp=this._tree[idx1]
        this._tree[idx1]=this._tree[idx2]
        this._tree[idx2]=tmp
    }

    //自底向上使堆符合规则
    _adaptUp(idx){
        if(idx===0) return
        let parentIdx=this._parent(idx)
        while (this._tree[idx][this._key]>this._tree[parentIdx][this._key]) { //如果子节点比父节点大,则交换位置
            this._swap(idx, parentIdx)
            idx = parentIdx
            parentIdx = this._parent(idx)
        }
    }

    //自顶向下使堆符合规则
    _adaptDown(idx){
        let left=this._leftChild(idx)
        let right=this._rightChild(idx)
        let size=this.getSize()
        let maxPos=left
        while (idx

step2:实现优先队列

class PriorityQueue{
    
    //构造方法,传入需要排序的key
    constructor(key) {
        this._data = new MaxHeap(key)
    }
    
    //获得队列长度
    getSize(){
        return this._data.getSize()
    }
    
    //获得队首对象
    getFront(){
        return this._data.getFront()
    }
    
    //弹出队首元素
    dequeue(){
        return this._data.extractMax()
    }
    
    //加入队列
    enqueue(e){
        this._data.add(e)
    }
    
    //清空队列
    clear(){
        this._data.clear()
    }
    
    //判断队列是否为空
    isEmpty(){
        return this._data.getSize()===0
    }

}

step3:例子验证

function   test1(){
    let  result=[
        {name:'李四',age:24},
        {name:'赵八',age:38},
        {name:'张三',age:13},
        {name:'王五',age:25},
        {name:'吴七',age:27}
        ]


    let  queue=new PriorityQueue("age")

    //数据加入队列
    for (let i=0;i

结果展示:

赵八====38====Queue size==4
吴七====27====Queue size==3
王五====25====Queue size==2
李四====24====Queue size==1
张三====13====Queue size==0

你可能感兴趣的:(数据结构和算法,JavaScrip)