我的理解是,js 语言中其实没有栈和队列这一引用类型(有用数组的基础方法push()和pop()模拟栈,shift()和push()模拟队列,栈和队列更复杂的功能需要自己写),这些概念以及方法都是通过对数组中一些方法的组合和封装来达到的。 数组中一些常用的方法有:
- every 对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true
- filter 对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组
- forEach 对数组中的每一项运行给定函数。这个方法没有返回值
- join 将所有的数组元素连接成一个字符串
- indexOf 返回第一个与给定参数相等的数组元素的索引,没有找到则返回-1
- lastIndexOf 返回在数组中搜索到的与给定参数相等的元素的索引里最大的值
- map 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
- reverse 颠倒数组中元素的顺序,原先第一个元素现在变成最后一个,同样原先的最后一个元素变成了现在 的第一个
- slice 传入索引值,将数组里对应索引范围内的元素作为新数组返回
- some 对数组中的每一项运行给定函数,如果任一项返回true,则返回true
- sort 按照字母顺序对数组排序,支持传入指定排序方法的函数作为参数
- toString 将数组作为字符串返回
- valueOf 和toString 类似,将数组作为字符串返回
栈: 栈中一些常用的方法有(可以自己再加方法):
- push(element(s)) :添加一个(或几个)新元素到栈顶。
- pop():移除栈顶的元素,同时返回被移除的元素。
- peek() :返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返 回它)。
- isEmpty():如果栈里没有任何元素就返回true,否则返回false。
- clear():移除栈里的所有元素。
- size() :返回栈里的元素个数。这个方法和数组的length属性很类似。
//栈
//首先通过创建一个类来表示栈
function Stack(){
var items=[];
this.push=function(elements){
items.push(elements);
};
this.pop=function(){
return items.pop();
};
this.peek=function(){
return items[items.length-1];
};
this.isEmpty=function(){
return items.length==0;
};
this.clear=function(){
items=[];
};
this.size=function(){
return items.length;
};
this.print=function(){
return items.toString();
}
}
//使用Stack类
var stack=new Stack();
console.log(stack.isEmpty());//true
stack.push(4);
stack.push(5);
console.log(stack.print());//4,5
console.log(stack.peek());//5
栈的实例:
//实例:利用栈将十进制转换为二进制
var decimalism=233;
var binary=new Stack();
var result='';
while(decimalism>0){
binary.push(parseInt(decimalism%2));
decimalism=parseInt(decimalism/2);
}
while(!binary.isEmpty()){
result=result+binary.pop().toString();
}
console.log(result);//11101001
队列: 队列中一些常用的方法有(可以自己再加方法):
- enqueue(element(s)):向队列尾部添加一个(或多个)新的项。
- dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素。
- front():返回队列中第一个元素——最先被添加,也将是最先被移除的元素。队列不 做任何变动(不移除元素,只返回元素信息——与Stack 类的peek方法非常类似)。
- isEmpty():如果队列中不包含任何元素,返回true,否则返回false 。
- size() :返回队列包含的元素个数,与数组的length属性类似。
//创建队列
function Queue(){
var items=[];
this.enqueue=function(elements){
items.push(elements);
};
this.dequeue=function(){
return items.shift();
};
this.front=function(){
return items[0];
};
this.isEmpty=function(){
return items.length==0;
};
this.clear=function(){
items=[];
};
this.size=function(){
return items.length;
};
this.print=function(){
console.log(items.toString());
};
}
var queue=new Queue();
queue.enqueue("Anna");
queue.print();//Anna
//...
优先队列:
//优先队列
function PriorityQueue(){
var items=[];
function QueueElement(element,priority){
this.elements=element;
this.priority=priority;
}
this.isEmpty=function(){
return items.length==0;
};
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++){
if(queueElement.priority<items[i].priority){
items.splice(i,0,queueElement);
added=true;
break;
}
}
}
if(!added){
items.push(queueElement);
}
};
this.print=function(){
console.log(items);
};
//其他方法与默认队列一致
}
//调用
var priorityQueue=new PriorityQueue();
priorityQueue.enqueue("Anna",3);
priorityQueue.enqueue("Bob",1);
priorityQueue.enqueue("Cindy",2);
priorityQueue.print();
循环队列(在队列的基础上进行特殊的调用)
//模拟击鼓传花
function hotPotato(nameList,num){
var queue=new Queue();
for(var i=0; i<nameList.length; i++){
queue.enqueue(nameList[i]);
}
var eliminated='';
while(queue.size()>1){
for(var i=0; i<num; i++){
queue.enqueue(queue.dequeue());
}
eliminated=queue.dequeue();
console.log(eliminated+"在击鼓传花游戏中被淘汰");
}
return queue.dequeue();
}
var names=["John","Jack","Camila","Ingrid","Carl"];
var winner=hotPotato(names,4);
console.log("胜利者"+winner);