1.使用队列:方块舞的舞伴分配问题                                    

前面我们提到过,经常用队列模拟排队的人。下面我们使用队列来模拟跳方块舞的人。当
男男女女来到舞池,他们按照自己的性别排成两队。当舞池中有地方空出来时,选两个队
列中的第一个人组成舞伴。他们身后的人各自向前移动一位,变成新的队首。当一对舞伴
迈入舞池时,主持人会大声喊出他们的名字。当一对舞伴走出舞池,且两排队伍中有任意
一队没人时,主持人也会把这个情况告诉大家。
为了模拟这种情况,我们把跳方块舞的男男女女的姓名储存在一个文本文件中:
 
下面是程序代码的实现:
<script type="text/javascript">
function Queue(){
this.dataStore = [];
this.enqueue = enqueue;
this.dequeue = dequeue;
this.front = front;
this.back = back;
this.toString = toString;
this.empty = empty;
this.count = count;
} /**
* 向队尾添加一个元素
*/
function enqueue(element){
this.dataStore.push(element);
} /**
* 删除队首的元素:
*/
function dequeue(){
this.dataStore.shift();
} /**
* 读取队首的元素:
*/
function front(){
return this.dataStore[0];
} /**
* 读取队尾的元素:
*/
function back(){
return this.dataStore[this.dataStore.length - 1];
} /**
* 显示队列内的所有元素
*/
function toString(){
var retStr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
retStr += this.dataStore[i] + "\n";
}
return retStr;
} /**
* 判断队列是否为空
*/
function empty(){
if(this.dataStore.length == 0){
return true;
}else{
return false;
}
} /**
* 显示队列中有多少个元素
*/
function count(){
return this.dataStore.length;
} //===================================使用Queue类=============================================
/**
* 每个舞者信息都被存储在一个Dancer 对象中
*/
function Dancer(name, sex) {
this.name = name;
this.sex = sex;
} /**
* 将舞者信息从文件中读到程序里来
* trim() 函数除去了每行字符串后的空格
* 根据性别,将舞者加入不同的队列
*/
function getDancers(males, females){
var names = read("dancers.txt").split("\n");
for (var i = 0; i < names.length; ++i) {
names[i] = names[i].trim();
}
for (var i = 0; i < names.length; ++i) {
var dancer = names[i].split(" ");
var sex = dancer[0];
var name = dancer[1];
if (sex == "F") {
females.enqueue(new Dancer(name, sex));
}else{
males.enqueue(new Dancer(name, sex));
}
}
} /**
* 将男性和女性组成舞伴,并且宣布配对结果
*/
function dance(males, females){
console.log("The dance partners are: \n");
while (!females.empty() && !males.empty()) {
person = females.dequeue();
console.log("Female dancer is: " + person.name);
person = males.dequeue();
console.log(" and the male dancer is: " + person.name);
}
} /**
*测试程序:
*/
var maleDancers = new Queue();
var femaleDancers = new Queue();
getDancers(maleDancers, femaleDancers);
dance(maleDancers, femaleDancers);
if (!femaleDancers.empty()) {
print(femaleDancers.front().name + " is waiting to dance.");
}
if (!maleDancers.empty()) {
print(maleDancers.front().name + " is waiting to dance.");
} //显示等候跳舞的人数
if (maleDancers.count() > 0) {
print("There are " + maleDancers.count() +" male dancers waiting to dance.");
}
if (femaleDancers.count() > 0) {
print("There are " + femaleDancers.count() +" female dancers waiting to dance.");
} </script>

2.使用队列对数据进行排序                                        

队列不仅用于执行现实生活中与排队有关的操作,还可以用于对数据进行排序。
计算机刚刚出现时,程序是通过穿孔卡输入主机的,每张卡包含一条程序语句。
这些穿孔卡装在一个盒子里,经一个机械装置进行排序。我们可以使用一组队列来模拟这一过程。
这种排序技术叫做基数排序,它不是最快的排序算法,但是它展示了一些有趣的队列使用方法。
 
对于0~99 的数字,基数排序将数据集扫描两次。
第一次按个位上的数字进行排序,第二次按十位上的数字进行排序。每个数字根据对应位上的数值被分在不同的盒子里。
假设有如下数字:
91, 46, 85, 15, 92, 35, 31, 22
 
经过基数排序第一次扫描之后,数字被分配到如下盒子中:

根据盒子的顺序,对数字进行第一次排序的结果如下:

91, 31, 92, 22, 85, 15, 35, 46
 
然后根据十位上的数值再将上次排序的结果分配到不同的盒子中:
最后,将盒子中的数字取出,组成一个新的列表,该列表即为排好序的数字:

15, 22, 31, 35, 46, 85, 91, 92
 
使用队列代表盒子,可以实现这个算法。

我们需要十个队列,每个对应一个数字。将所有队列保存在一个数组中,使用取余和除法操作决定个位和十位。
算法的剩余部分将数字加入相应的队列,根据个位数值对其重新排序,然后再根据十位上的数值进行排序,
结果即为排好序的数字。
 
下面是代码的实现:
<script type="text/javascript">
function Queue(){
this.dataStore = [];
this.enqueue = enqueue;
this.dequeue = dequeue;
this.front = front;
this.back = back;
this.toString = toString;
this.empty = empty;
this.count = count;
} /**
* 向队尾添加一个元素
*/
function enqueue(element){
this.dataStore.push(element);
} /**
* 删除队首的元素:
*/
function dequeue(){
return this.dataStore.shift();
} /**
* 读取队首的元素:
*/
function front(){
return this.dataStore[0];
} /**
* 读取队尾的元素:
*/
function back(){
return this.dataStore[this.dataStore.length - 1];
} /**
* 显示队列内的所有元素
*/
function toString(){
var retStr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
retStr += this.dataStore[i] + "\n";
}
return retStr;
} /**
* 判断队列是否为空
*/
function empty(){
if(this.dataStore.length == 0){
return true;
}else{
return false;
}
} /**
* 显示队列中有多少个元素
*/
function count(){
return this.dataStore.length;
} //===================================使用Queue类=============================================
/**
* 根据相应位(个位或十位)上的数值,将数字分配到相应队列
* nums: 待排序的数组
* queues: 队列数组
* n: nums的length
* 参数digit 1-按照个位数排序,10-按照十位数排序
*/
function distribute(nums, queues, n, digit){
for(var i=0; i<n; i++){
if(digit == 1){
queues[nums[i]%10].enqueue(nums[i]);
}else{
var k = Math.floor(nums[i]/10);
queues[k].enqueue(nums[i]);
}
}
} /**
* 从队列中收集数字的函数
*/
function collect(queues, nums){
var i=0;
for(var j=0; j<queues.length; j++){
while(!queues[j].empty()){
nums[i++] = queues[j].dequeue();
}
}
} //测试程序
//1.定义queues 和 nums
var queues = [];
for (var i = 0; i < 10; ++i) {
queues[i] = new Queue();
}
var nums = [];
for (var i = 0; i < 10; ++i) {
nums[i] = Math.floor(Math.random() * 101);
} console.log("Before radix sort: ");
console.log(nums);
distribute(nums, queues, nums.length, 1); //按照个位数进行第一次排序
collect(queues, nums); //对按照个位数排好序的队列,每个队列挨排出列,组成新的数组
distribute(nums, queues, nums.length, 10); //按照十位数进行第二次排序
collect(queues, nums);
console.log("After radix sort: ");
console.log(nums); </script>

打印出来如下:

3.优先队列:

在一般情况下,从队列中删除的元素,一定是率先入队的元素。
但是也有一些使用队列的应用,在删除元素时不必遵守先进先出的约定。这种应用,需要使用一个叫做优先队列的数据结构来进行模拟。
 
从优先队列中删除元素时, 需要考虑优先权的限制。
比如医院急诊科的候诊室,就是一个采取优先队列的例子。当病人进入候诊室时,分诊护士会评估患者病情的严重程度,然后给一个优先级代码。高优先级的患者先于低优先级的患者就医,同样优先级的患者按照先来先服务的顺序就医。
 
先来定义存储队列元素的对象,然后再构建我们的优先队列系统:
function Patient(name, code) {
  this.name = name;
  this.code = code;
}
变量code 是一个整数,表示患者的优先级或病情严重程度。
 
现在需要重新定义dequeue() 方法,使其删除队列中拥有最高优先级的元素。
我们规定:优先码的值最小的元素优先级最高。
新的dequeue() 方法遍历队列的底层存储数组,从中找出优先码最低的元素,然后使用数组的splice() 方法删除优先级最高的元素。
 
最后,需要定义toString() 方法来显示Patient 对象。
 
 
代码实现如下:
<script type="text/javascript">
function Queue(){
this.dataStore = [];
this.enqueue = enqueue;
this.dequeue = dequeue;
this.front = front;
this.back = back;
this.toString = toString;
this.empty = empty;
this.count = count;
} /**
* 向队尾添加一个元素
*/
function enqueue(element){
this.dataStore.push(element);
} /**
* 使用简单的顺序查找方法寻找优先级最高的元素(优先码越小优先级越高,比如,1 比5 的优先级高)
* 返回包含一个元素的数组——从队列中删除的元素。
*
* 假设第0个位置的优先级最小。
* 找到比这个优先级更小的位置,然后更新位置。
*/
function dequeue(){
var priority = 0;
for(var i=1; i<this.dataStore.length; i++){
if(this.dataStore[i].code < this.dataStore[priority].code){
priority = i;
}
} return this.dataStore.splice(priority, 1);
} /**
* 读取队首的元素:
*/
function front(){
return this.dataStore[0];
} /**
* 读取队尾的元素:
*/
function back(){
return this.dataStore[this.dataStore.length - 1];
} /**
* 显示队列内的所有元素
*/
function toString(){
var retStr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
retStr += this.dataStore[i].name + ", code: "+ this.dataStore[i].code + "\n";
}
return retStr;
} /**
* 判断队列是否为空
*/
function empty(){
if(this.dataStore.length == 0){
return true;
}else{
return false;
}
} /**
* 显示队列中有多少个元素
*/
function count(){
return this.dataStore.length;
} //===================================使用Queue类=============================================
function Patient(name, code) {
this.name = name;
this.code = code;
} //优先队列的实现:
var p = new Patient("Smith",5);
var ed = new Queue();
ed.enqueue(p);
p = new Patient("Jones", 4);
ed.enqueue(p);
p = new Patient("Fehrenbach", 6);
ed.enqueue(p);
p = new Patient("Brown", 1);
ed.enqueue(p);
p = new Patient("Ingram", 1);
ed.enqueue(p);
console.log(ed.toString());
console.log("-------------------------------"); var seen = ed.dequeue();
console.log("Patient being treated: " + seen[0].name);
console.log("Patients waiting to be seen: ");
console.log(ed.toString());
console.log("-------------------------------"); // 下一轮
var seen = ed.dequeue();
console.log("Patient being treated: " + seen[0].name);
console.log("Patients waiting to be seen: ");
console.log(ed.toString());
console.log("-------------------------------"); var seen = ed.dequeue();
console.log("Patient being treated: " + seen[0].name);
console.log("Patients waiting to be seen: ");
console.log(ed.toString()); </script>

打印结果:

数据结构与算法JavaScript描述——使用队列的更多相关文章

  1. 《数据结构与算法JavaScript描述》

    <数据结构与算法JavaScript描述> 基本信息 作者: (美)Michael McMillan 译者: 王群锋 杜欢 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9 ...

  2. 翻阅《数据结构与算法javascript描述》--数组篇

    导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScript 中的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性 ...

  3. 数据结构与算法javascript描述

    <数据结构与算法javascript描述>--数组篇 导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScri ...

  4. 列表的实现-----数据结构与算法JavaScript描述 第三章

    实现一个列表 script var booklist = new List(); booklist.append('jsbook'); booklist.append('cssbook'); book ...

  5. 《数据结构与算法JavaScript描述》中的一处错误

    最近在看<数据结构与算法JavaScript描述>这本书,看到选择排序这部分时,发现一个比较大的错误. 原书的选择排序算法是这样的: function selectionSort() { ...

  6. 数据结构与算法 Javascript描述

    数据结构与算法系列主要记录<数据结构与算法 Javascript描述>学习心得

  7. 读后感:数据结构与算法JavaScript描述

    本书看完,对常见的数据结构与算法从概念上有了更深入的理解. 书中关于数组.栈和队列.链表.字典.散列.集合.二叉树.图.排序.检索.动态规划.贪心算法都有详细的介绍.算是一本不错的学习书籍. 栈和队列 ...

  8. 数据结构与算法JavaScript描述——队列

    注:澄清一个bug: /** * 删除队首的元素: */ function dequeue(){ return this.dataStore.shift(); } 应该有return:   队列是一种 ...

  9. 队列--数据结构与算法JavaScript描述(5)

    队列 Queue 概念 队列是一种列表,但队列只能在队尾插入元,在队首删除元素. 队列是一种先进先出的数据结构,用于存储按顺序排列的数据,被用在很多地方,比如提交操作系统执行的一系列进程.打印任务池等 ...

随机推荐

  1. QT 相关书籍

    qt qucik 核心编程 个人觉得此书写得非常之好....这位作者的另外一本虽然没看过,估计也不错 https://bbs.csdn.net/topics/390942701?list=lz qt5 ...

  2. OC-NSString

    ========================== 面向对象编程进阶和字符串 ========================== Δ一.类的设计模式—单例 [单例]程序允许过程中,有且仅有一块内存 ...

  3. Java反射-初步入门

    Java反射-初步入门 学反射先了解什么是反射. 百度百科:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动 ...

  4. reactNative 的一些学习

    手把手视频 学习资料大全 入门系列

  5. Http权威指南(服务器、缓存)

    对于web服务器(软件)大家应该不会陌生,常见的web服务器有Apache.IIS.Tomcat.Nginx.Jetty等等. 1.基本功能 几乎所有的web服务器都会执行以下几项同样的任务: 1.建 ...

  6. gradle Could not create service of type CrossBuildFileHashCache using BuildSessionScopeServices.crea

    gradle Could not create service of type CrossBuildFileHashCache using BuildSessionScopeServices.crea ...

  7. nginx and node.js配合使用 helloworld

    nginx是最好的反向代理服务器. Node.js是... 好吧 ,不介绍了,猛击这里 现在小介绍下怎么用nginx和node.js配合使用. 先写个helloworld.js var http =  ...

  8. 如何只更新datetime类型字段中的日期

    UPDATE  [dbo].[Order]       SET     CreateDate = STUFF(CONVERT(VARCHAR(50),CreateDate,126) ,1, 10, ' ...

  9. QUnit使用

    什么是单元测试 每个单元测试就是一段用于测试一个模块或接口是否能达到预期结果的代码. QUnitjs 概念Qunit是一款强大的用于帮助调试代码的,JavaScript单元测试框架.是jQuery的官 ...

  10. C函数说明

    输入函数scanf_s()   比如:char d[20];写成scanf_s("%s",d,20); 输出函数printf()      比如:printf("hell ...