5.队列

259 阅读2分钟

队列

队列是一种列表, 队列的特点是先进先出,

  • 出队(插入元素)的元素只能是队列首位置的元素
  • 入队(删除元素)的元素只能位于队列的尾部
  • 获取对头的元素的操作叫peek

队列类的实现

function Queue() {
    this.dataStore = []
    this.pos = 0
}
Queue.prototype = {
    length: function() {
        return this.dataStore.length
    },
    empty: function() {
        return this.dataStore.length > 0 ? false : true
    },
    front: function() {
        return this.dataStore[0]
    },
    back: function() {
        return this.dataStore[this.pos -1]
    },
    enqueue: function(element) {
        this.dataStore.push(element)
        this.pos ++ 
    },
    dequeue: function() {
        this.dataStore.shift()
        -- this.pos
    },
    toString: function() {
        return this.dataStore
    }
}
let eg = new Queue()
eg.enqueue('PUSH')
eg.enqueue('POP')
eg.enqueue('SHIFT')
eg.enqueue('UNSHIFT')

方块舞的舞伴分配问题

一组数据表示舞会上的男男女女,将他们按性别排成两队, 将队列按对首进行分配并宣布他们的名字

let dancer = [    {name:'Ari', sex:'f'},    {name:'John', sex:'m'},    {name:'Pt', sex:'m'},    {name:'Shelly', sex:'f'},    {name:'Mickel', sex:'m'},    {name:'Naah', sex:'f'},    {name:'Judy', sex:'m'},    {name:'Elven', sex:'f'},    {name:'Watii', sex:'m'},    {name:'Queen', sex:'f'},    {name:'Mitty', sex:'f'},    {name:'Bruce', sex:'m'},    {name:'Frank', sex:'f'},    {name:'Rose', sex:'f'},    {name:'Anderson', sex:'f'},    {name:'Williams', sex:'m'},    {name:'Otiz', sex:'m'},    {name:'Martin', sex:'m'},    {name:'Ruff', sex:'f'},    {name:'Adeny', sex:'f'},]
let fQueue = new Queue()
let mQueue = new Queue()
dancer.forEach(item => {
    if(item.sex == 'f') {
        fQueue.enqueue(item)
    } else {
        mQueue.enqueue(item)
    }
})
do {
    if(!fQueue.empty() && !mQueue.empty()) {
        
        console.log(`Dancer: gentleMan is ${mQueue.front().name} and lady is ${fQueue.front().name}`)
        mQueue.dequeue()
        fQueue.dequeue()
    }
} while (!fQueue.empty() && !mQueue.empty())
if(fQueue.length > 0 ) {
    console.log(`${fQueue.length()} famales watting`)
}
if(mQueue.length > 0) {
    console.log(`${mQueue.length()} males watting`)
}

使用队列对数组进行排序

  • 基数排序 首先按个位将数字入队到不同的队列
    1. 原数组 45 39 71 15 42 96 31 62 27 24
    2. 一轮操作后 71 31 42 62 24 45 15 96 27 然后将 数字按照十位数重新入队到队列中
    3. 15 24 27 31 42 45 62 71 96
/*
    * 基数排序
    */
    let queues = []
    for (let i = 0; i < 10; i++) {
        queues[i] = new Queue()
    }
    let arr = [45, 39, 71, 15, 42, 96, 31, 61, 62, 27, 24, 99, 01]
    function distribute(arr, queues, digit) {
        for(let i=0; i< arr.length; i++) {
            if(digit == 1) {
                queues[arr[i]%10].enqueue(arr[i])
            } else {
                queues[Math.floor(arr[i]/10)].enqueue(arr[i])
            }
        }
    }
    function collect(queue) {
        let nums = []
        for(let i = 0; i< queue.length; i++) {
            let item = queue[i] 
            while(!item.empty()) {
                nums.push(item.front())
                item.dequeue()
            }
        }
        return nums
    }
    distribute(arr, queues, 1)
    distribute(collect(queues), queues, 10)
    console.log(collect(queues))

优先队列

正常情况下 出队的元素都是先入队的元素, 但实际情况下有的元素要优先出队 例如病房的病人要加急插队的情况

    /**
     * 优先队列
    */
    Queue.prototype.priorityDequeue = function(element) {
        this.dataStore.splice(this.dataStore.indexOf(element), 1)
        --this.pos
    }   

完整代码

function Queue() {
        this.dataStore = []
        this.pos = 0
    }
    Queue.prototype = {
        length: function() {
            return this.dataStore.length
        },
        empty: function() {
            return this.dataStore.length > 0 ? false : true
        },
        front: function() {
            return this.dataStore[0]
        },
        back: function() {
            return this.dataStore[this.pos -1]
        },
        enqueue: function(element) {
            this.dataStore.push(element)
            this.pos ++ 
        },
        dequeue: function() {
            this.dataStore.shift()
            -- this.pos
        },
        toString: function() {
            return this.dataStore
        }
    }
    let eg = new Queue()
    eg.enqueue('PUSH')
    eg.enqueue('POP')
    eg.enqueue('SHIFT')
    eg.enqueue('UNSHIFT')

    let dancer = [        {name:'Ari', sex:'f'},        {name:'John', sex:'m'},        {name:'Pt', sex:'m'},        {name:'Shelly', sex:'f'},        {name:'Mickel', sex:'m'},        {name:'Naah', sex:'f'},        {name:'Judy', sex:'m'},        {name:'Elven', sex:'f'},        {name:'Watii', sex:'m'},        {name:'Queen', sex:'f'},        {name:'Mitty', sex:'f'},        {name:'Bruce', sex:'m'},        {name:'Frank', sex:'f'},        {name:'Rose', sex:'f'},        {name:'Anderson', sex:'f'},        {name:'Williams', sex:'m'},        {name:'Otiz', sex:'m'},        {name:'Martin', sex:'m'},        {name:'Ruff', sex:'f'},        {name:'Adeny', sex:'f'},        ]
    let fQueue = new Queue()
    let mQueue = new Queue()
    dancer.forEach(item => {
        if(item.sex == 'f') {
            fQueue.enqueue(item)
        } else {
            mQueue.enqueue(item)
        }
    })
    do {
        if(!fQueue.empty() && !mQueue.empty()) {
            
            console.log(`Dancer: gentleMan is ${mQueue.front().name} and lady is ${fQueue.front().name}`)
            mQueue.dequeue()
            fQueue.dequeue()
        }
    } while (!fQueue.empty() && !mQueue.empty())
    if(fQueue.length > 0 ) {
        console.log(`${fQueue.length()} famales watting`)
    }
    if(mQueue.length > 0) {
        console.log(`${mQueue.length()} males watting`)
    }


    /*
    * 基数排序
    */
    let queues = []
    for (let i = 0; i < 10; i++) {
        queues[i] = new Queue()
    }
    let arr = [45, 39, 71, 15, 42, 96, 31, 61, 62, 27, 24, 99, 01]
    function distribute(arr, queues, digit) {
        for(let i=0; i< arr.length; i++) {
            if(digit == 1) {
                queues[arr[i]%10].enqueue(arr[i])
            } else {
                queues[Math.floor(arr[i]/10)].enqueue(arr[i])
            }
        }
    }
    function collect(queue) {
        let nums = []
        for(let i = 0; i< queue.length; i++) {
            let item = queue[i] 
            while(!item.empty()) {
                nums.push(item.front())
                item.dequeue()
            }
        }
        return nums
    }
    distribute(arr, queues, 1)
    distribute(collect(queues), queues, 10)
    console.log(collect(queues))

    /**
     * 优先队列
    */
    Queue.prototype.priorityDequeue = function(element) {
        this.dataStore.splice(this.dataStore.indexOf(element), 1)
        --this.pos
    }