js数据结构中的队列
队列的两种主要操作是:向队列中插入新元素和删除队列中的元素。插入操作也叫做入队,删除操作也叫做出队。入队操作在队尾插入新元素,出队操作删除队头的元素。
队列的另外一项重要操作是读取队头的元素。这个操作叫做 peek() 。该操作返回队头元素,但不把它从队列中删除。除了读取队头元素,我们还想知道队列中存储了多少元素,可以使用 length 属性满足该需求;要想清空队列中的所有元素,可以使用 clear() 方法来实现。
一个用数组实现的队列:
使用数组来实现队列看起来顺理成章。JavaScript 中的数组具有其他编程语言中没有的优点,数组的 push() 方法可以在数组末尾加入元素, shift() 方法则可删除数组的第一个元素。push() 方法将它的参数插入数组中第一个开放的位置,该位置总在数组的末尾,即使是个空数组也是如此。请看下面的例子:
/**
* Created by Administrator on 2016/12/9.
*/
function Queue() {
this.dataStore=[];
this.enqueue=enqueue;
this.dequeue=dequeue;
this.dequeuePriority=dequeuePriority;
this.front=front;
this.back=back;
this.toString=toString;
this.empty=empty;
}
//向队尾添加一个元素:
function enqueue(element) {
this.dataStore.push(element);
}
//删除队首的元素:
function dequeue() {
return this.dataStore.shift();
}
function dequeuePriority() {//优先队列的实现
var priority = this.dataStore[0].code;
for (var i = 1; i < this.dataStore.length; ++i) {
if (this.dataStore[i].code < priority) {
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 reStr="";
for (var i=0;i<this.dataStore.length;i++){
reStr+=this.dataStore[i]+" ";
}
return reStr;
}
function empty() {
if(this.dataStore.length==0){
return true;
}
else{
return false;
}
}
测试代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="Queue.js"></script>
<script>
var q = new Queue();
q.enqueue("AAA");
q.enqueue("BBB");
q.enqueue("CCC");
q.enqueue("DDD");
console.log("asd: "+q.toString());
q.dequeue();
console.log(q.toString());
console.log("Front of queue: " + q.front());
console.log("Back of queue: " + q.back());
/**************方块舞的舞伴分配问题********************/
function Dancer(name, sex) {
this.name = name;
this.sex = sex;
}
function getDancers(males, females) {
var infos = [];
infos.push("F 111");
infos.push("M AAA");
infos.push("M BBB");
infos.push("M CCC");
infos.push("F 222");
infos.push("M DDD");
infos.push("F 333");
infos.push("F 444");
infos.push("F 555");
infos.push("F 666");
for (var i = 0; i < infos.length; ++i) {
infos[i] = infos[i].trim();
}
for (var i = 0; i < infos.length; ++i) {
var dancer = infos[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: " + person.name);
person = males.dequeue();
console.log(" male: " + person.name);
}
console.log();
}
var maleDancers = new Queue();
var femaleDancers = new Queue();
getDancers(maleDancers, femaleDancers);
dance(maleDancers, femaleDancers);
if (!femaleDancers.empty()) {
console.log(femaleDancers.front().name + " is waiting to dance.");
}
if (!maleDancers.empty()) {
console.log(maleDancers.front().name + " is waiting to dance.");
}
</script>
</head>
<body>
</body>
</html>
优先队列
在一般情况下,从队列中删除的元素,一定是率先入队的元素。但是也有一些使用队列的应用,在删除元素时不必遵守先进先出的约定。这种应用,需要使用一个叫做优先队列的数据结构来进行模拟。
现在需要重新定义 dequeue() 方法,使其删除队列中拥有最高优先级的元素。我们规定:优先码的值最小的元素优先级最高。新的 dequeue() 方法遍历队列的底层存储数组,从中找出优先码最低的元素,然后使用数组的 splice() 方法删除优先级最高的元素。新的dequeue() 方法定义如下所示:
function dequeuePriority() {
var priority = this.dataStore[0].code;
for (var i = 1; i < this.dataStore.length; ++i) {
if (this.dataStore[i].code < priority) {
priority = i;
}
}
return this.dataStore.splice(priority,1);
}