创建一个类来表示栈:
function Stack () {
var items = []; //选择数组来保存栈里的元素
this.push = function (element) {//这个方法负责往栈里添加新元素(只添加到栈顶)
items.push(element);
};
this.pop = function () {//这个方法主要用来移除栈里的元素(遵从先进后出)
return items.pop();
};
this.peek = function () {//这个方法负责返回栈顶的元素
return items[items.length - 1];
};
this.isEmpty = function () {//如果栈为空的话返回true,否则就返回false
return items.length == 0;
};
this.size = function () {//这个方法返回栈的长度
return items.length;
};
this.clear = function () {//这个方法用来移除栈里的所有元素,把栈清空
items = [];
};
this.print = function () {
console.log(items.toString());//把栈里的元素都输出到控制台
}
}
通过使用Stack类来解决一些问题,如将十进制数转为二进制数:
function divideBy2 (decNumber) {
var remStack = new Stack();
var rem = 0, binaryString = '';
while (decNumber > 0) {
rem = Math.floor(decNumber % 2);
remStack.push(rem);
decNumber = Math.floor(decNumber / 2);
}
while (!remStack.isEmpty()) {
binaryString += remStack.pop().toString();
}
return binaryString;
}
修改上面代码,就可实现将十进制数转为其他进制的数:
function baseConverter (decNumber, base) {
var remStack = new Stack();
var rem = 0, baseString = '', digits = '0123456789ABCDEF';
while (decNumber > 0) {
rem = Math.floor(decNumber % base);
remStack.push(rem);
decNumber = Math.floor(decNumber / base);
}
while (!remStack.isEmpty()) {
/*
*十进制转二进制,余数是0或1;十进制转八进制,余数是0到7;
*十进制转十六进制,余数是0到9加上A、B、C、D、E、F
*/
baseString += digits[remStack.pop()];
}
return baseString;
}
创建一个类来表示栈:
function Queue () {
var items = [];
this.enqueue = function (element) {//负责向队列添加新元素
items.push(element);
};
this.dequeue = function () {//从队列中移除第一个元素
return items.shift();
};
this.front = function () {//返回队列最前面的项
return items[0];
};
this.isEmpty = function () {//如果队列为空,返回true,否则返回false
return items.length == 0;
};
this.size = function () {//返回队列到长度
return items.length;
};
this.print = function () {//把队列里的元素都输出到控制台
console.log(items.toString());
};
}
创建优先队列:(优先队列 元素的添加和删除是基于优先级的)
function PriorityQueue () {
var items = [];
function QueueElement (element, priority) {//创建这个特殊的元素,用来包含要添加到队列的元素
this.element = element;
this.priority = priority;
}
this.enqueue = function (element, priority) {
var queueElement = new QueueElement(element, priority);
if (this.isEmpty()) {
items.push(queueElement);//如果队列为空,直接将元素入列,否则就需要比较该元素与其他元素的优先级
} else {
var added = false;
for (var i = 0; i < items.length; i++) {
/*
当找到一个比要添加的元素的priority值更大(优先级更低)的项时,就把新元素
插入到它之前(对于优先级相同,但是先添加到队列的元素,同样遵循先进先出的原则)
*/
if (queueElement.priority < items[i].priority) {
items.splice(i, 0, queueElement);//一旦找到priority值更大的元素,就插入新元素
added = true;
break;
}
}
if (!added) {//如果要添加的元素的priority值大于任何已有的的元素,把它添加到队列的末尾
items.push(queueElement);
}
}
};
this.dequeue = function () {
return items.shift();
};
this.front = function () {
return items[0];
};
this.size = function () {
return items.length;
};
this.isEmpty = function () {
return items.length == 0;
};
this.print = function () {
// console.log(items.toString());
console.log(items);
};
}
var priorityQueue = new PriorityQueue();
priorityQueue.enqueue('John', 2);
priorityQueue.enqueue('Jack', 1);
priorityQueue.enqueue('Camila', 1);
priorityQueue.print();
在下图中可以看到每条命令的结果:
这里实现的优先队列称为 最小优先队列,因为优先级的值较小的元素被放置在队列最前面。最大优先队列则与之相反。
<br>
创建一个循环队列,并用循环队列实现一个击鼓传花的小应用:
function hotPotato (nameList, num) {
var queue = new Queue();//要用到实现的Queue类
for (var i = 0; i < nameList.length; i++) {
queue.enqueue(nameList[i]);
}
var eliminate = '';
while (queue.size() > 1) {
for (var i = 0; i < num; i++) {
queue.enqueue(queue.dequeue());//队列开头移除一项,再将其添加到队列末尾
}
eliminate = queue.dequeue();//一旦传递次数达到给定的数字,拿着花的人就被淘汰了(从队列末尾移除)
console.log(eliminate + '在击鼓传花游戏中被淘汰');
}
return queue.dequeue();
}
var names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl'];
var winner = hotPotato(names, 7);
console.log('胜利者:' + winner);
以上小游戏的输出如下:
Camila在击鼓传花游戏中被淘汰
Jack在击鼓传花游戏中被淘汰
Carl在击鼓传花游戏中被淘汰
Ingrid在击鼓传花游戏中被淘汰
胜利者:John