Javascript数据结构算法之队列(舞伴分配,基数排序,模拟优先就诊病人)

本文详细介绍了队列这一数据结构的概念与实现,并通过具体的案例展示了队列在实际问题中的应用,包括舞伴分配、基数排序以及优先队列的设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

队列是一种先进先出(FIFO)的数据结构,数据只能在队尾插入或者在队首删除。队列用在很多地方,比如提交操作系统的一系列进程,打印任务池等,一些仿真系统用队列模拟银行或杂货店排队的顾客。

接下来,将从3个方面来深入理解和使用栈这种数据结构。

  • 抽象数据类型定义
  • 队列的JS实现
  • 解决实际问题

抽象数据类型定义

属性及方法作用
enqueue()在队尾插入元素
dequeue()在队首删除元素
front()读取队首元素
back()读取队尾元素
empty()判断队列是否为空
clear()清空队列
count()记录队列长度
dataStore使用数组存储数据

队列的JS实现

使用构造器调用模式,这是一套类似类的对象构建语法,通过在函数前面加上new调用,同时this会绑定到这个新对象上。

//Queue.js
//Queue对象定义
function Queue(){
    this.dataStore = [];
    this.enqueue = enqueue;
    this.dequeue = dequeue;
    this.empty = empty;
    this.front = front;
    this.back = back;
    this.count = count;
    this.toString = toString;//显示队列元素
}
function enqueue(element){
    this.dataStore.push(element);//直接使用数组方法
}
function dequeue(){
    return this.dataStore.shift();//直接使用数组方法
}
function empty(){
    if(this.dataStore.length == 0)
        return true;
    else
        return false;
}
function clear(){
    this.dataStore.length = 0;
}
function front(){
    return this.dataStore[0];
}
function back(){
    return this.dataStore[this.dataStore.length - 1];
}
function count(){
    return this.dataStore.length;
}
function toString(){
    var str = "";
    for(var i=0; i<this.dataStore.length; i++)
    {
        str += this.dataStore[i]+"\n"
    }
    return str;
}
//实例化Queue对象
var oneQueue = new Queue();

队列的实际应用

(一)网页展示

这里写图片描述

(二)html代码

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Queue Applications</title>
    <script src="queue.js" type="text/javascript"></script>
    <script src="app.js" type="text/javascript"></script>   
</head>
<style>
div {
    width: 60%;
    margin: 30px auto;
    padding: 10px;
    border: 1px solid #333;
}
h2{
    text-align: center;
    margin: auto;
}
</style>
<body>
    <h2>方块舞问题</h2>
    <div>
        <form>
            <label for="file">请选择一个文件:</label>
            <input type="file" id="file" />
            <input type="button" value="读取文本文件" style="display:block;margin:20px 0;" onclick="readAsText()" />  
        </form>
        <textarea id="dancers_content" name="dancers_content"></textarea>
    </div>
    <div>
        <input type="button" value="入场者" onclick="getDancers()" />
        <textarea id="guests_name"></textarea>
        <input type="button" value="跳舞名单" onclick="goDance()" />
        <textarea id="dancers_name"></textarea>
    </div>
    ……
</body>
</html>

(三)Javascript方法

1. 舞伴分配

问题描述:当男男女女来到舞池,他们按照性别排成两队。当舞池有地方空出来时,选择两个队伍中第一个人组成舞伴。他们身后的人各自向前移动一位。

//app.js
var males = new Queue();
var females = new Queue();

function getDancers()
{
    //读取依次进来的人  
    var content = document.getElementById("dancers_content").firstChild.nodeValue;
    var names = content.split("\n");

    //将人们按照性别分成两队
    for(var j=0; j<names.length; j++)
    {
        var dancer = names[j].split(" ");
        var dancer_name = dancer[1];
        var dancer_sex = dancer[0];

        if(dancer_sex=="F")
        {
            females.enqueue(new Dancer(dancer_name,dancer_sex));
        }
        else
        {
            males.enqueue(new Dancer(dancer_name,dancer_sex));
        }
    }

}

function goDance()
{
    var name = document.getElementById("dancers_name");
    name.innerHTML = "";//将结果显示在网页上

    while(!males.empty() && !females.empty())
    {
        name.innerHTML += "Female dancer is "+females.dequeue().name +"; Male dancer is "+males.dequeue().name+".\n";
    }
    if(males.empty())
    {
        name.innerHTML += females.count() +" female dancers are waiting."
    }
    if(females.empty())
    {
        name.innerHTML += males.count() +" male dancers are waiting."
    }
}
2. 基数排序

基数排序具体原理可以参考百度百科。

//app.js

//生成含有12个元素的初始数组,待排序
var startNums = [];
function beforeSort(){
    for(var i=0; i<12; i++)
    {
        startNums[i] = Math.floor(Math.random()*101+1);
    }
    //将生成的数组显示在网页上
    var originalNums = document.getElementById("original_nums");
    originalNums.value = "";
    for(var i=0; i<startNums.length; i++)
    {
        originalNums.value += startNums[i]+" ";
    }
}
//有10个队列,编号分别为0-9
var globalQueues = [];
for(var i=0; i<10; i++)
{
    globalQueues[i] = new Queue();
}

//根据数组中每个数字十位或者个位的数值,将数字分配到对应队列
function distribute(nums, queues, n, digit){
    for(var i=0; i<n; i++)
    {
        if(digit == 1)
        {
            queues[nums[i]%10].enqueue(nums[i]);
        }
        else
        {
            queues[Math.floor(nums[i]/10)].enqueue(nums[i]);
        }
    }
}
//从队列中收集数字
function collect(queues, nums)
{
    var i = 0;
    for(var digit = 0; digit <10; digit++)
    {
        while(!queues[digit].empty())
        {
            nums[i++] = queues[digit].dequeue();
        }
    }
}
//开始排序,先个位,再十位
function sort(){
    distribute(startNums, globalQueues, startNums.length, 1);
    collect(globalQueues, startNums);
    distribute(startNums, globalQueues, startNums.length, 10);
    collect(globalQueues, startNums);
    //将排序结果显示在网页上
    var sortedNums = document.getElementById("sorted_nums");
    sortedNums.value = "";
    for(var i=0; i<startNums.length; i++)
    {
        sortedNums.value += startNums[i]+" ";
    }
}
3. 优先队列

优先队列:在优先队列中删除元素时,需要考虑优先级的限制。

//app.js
//模拟医院急诊室,当病人进入门诊时,会根据病情严重情况,获得优先级排序。高优先级的患者先于低优先级的患者就医。

//构建病人对象,code为优先级,1为最高优先级
function Patient(name, code)
{
    this.name = name;
    this.code = code;
}

//优先队列只有出列操作不同于普通队列,需要先比较优先级
function pridequeue(){
    var entry = 0;
    for(var i=1; i<this.dataStore.length; i++)
    {
        if(this.dataStore[entry].code > this.dataStore[i].code)
            entry = i;
    }
    return this.dataStore.splice(entry, 1);
}

//模拟创建急诊病人的优先队列
var pri = new Queue();
pri.enqueue(new Patient("Fehrenback", 6));
pri.enqueue(new Patient("Jones", 4));
pri.enqueue(new Patient("Smith", 5));
pri.enqueue(new Patient("Brown", 1));
pri.enqueue(new Patient("Ingram", 1));

function showPri(){
    var firstP = pri.pridequeue();
    var secondP = pri.pridequeue();
    var thirdP = pri.pridequeue();
    //将优先出列的病人名字显示在网页上
    var priPatients = document.getElementById("pri_patients");
    priPatients.value = "1."+ firstP[0].name +  " 2."+ secondP[0].name +  " 3."+ thirdP[0].name;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值