栈
了解栈
栈(stock),是一种受限的线性表,后进先出。
有函数A调用函数B,函数B调用函数C,它们的进出栈情况是:
A压入栈,A执行时调用B,B压入栈。B执行时调用C,C执行完成。此时顺序为:栈底 A-B-C 栈顶。
C执行完成后弹出栈-B再弹出栈,最后A弹出栈。
思考:有6个元素按照6,5,4,3,2,1的顺序进栈,下列哪个不是正确的出栈顺序
A.5,4,3,6,1,2 B.4,5,3,2,1,6 C.3,4,6,5,2 ,1 D.2,3,4,1,5,6
解析:A: 6进栈5进栈,5出栈。4进栈,4出栈。3进栈,3出栈。2进栈1进栈,1出栈,2出栈。正确
B:6进栈5进栈4进栈,4出栈,5出栈。3进栈,3出栈。2进栈,2出栈。1进栈,1出栈。6出栈。正确
C:6进栈5进栈4进栈3进栈,3出栈,4出栈,下面是5出栈,所以错误
D:6进栈5进栈4进栈3进栈2进栈,2出栈,3出栈,4出栈。1进栈,1出栈。5出栈,6出栈。正确
栈结构的实现
基于数组实现
//封装栈类
function Stack(){
//栈的属性
this.items=[]
//1.将元素压入栈内
Stack.prototype.push=function(element){
this.items.push(element)
}
//2.从栈中取出元素
Stack.prototype.pop=function(){
return this.items.pop()
}
//3.查看栈顶元素
Stack.prototype.peek=function(){
return this.items[this.items.length-1]
}
//4.判断栈是否为空
Stack.prototype.isEmpty=function(){
return this.items.length ==0
}
//5.获取栈中元素的个数
Stack.prototype.size=function(){
return this.items.length
}
//6.toString方法
Stack.prototype.size=function(){
var resultStr=""
for(var i=0;i<this.items.length;i++){
resultStr+=this.item[i]+ ""
}
return resultStr
}
}
//栈的使用
let s=new Stack()
s.push(2)
思考:利用栈将十进制转换为二进制。
解析:1.将数字除以2,直到结果为0。记录得到的余数。2.将得到的余数从后到前排列起来,得到的就是二进制
//封装栈
function Stack(){
this.items=[]
Stack.prototype.push=function(element){
this.items.push(element)
}
Stack.prototype.pop=function(){
return this.items.pop()
}
Stack.prototype.peek=function(){
return this.items[this.items.length-1]
}
Stack.prototype.isEmpty=function(){
return this.items.length ==0
}
Stack.prototype.size=function(){
return this.items.length
}
Stack.prototype.size=function(){
var resultStr=""
for(var i=0;i<this.items.length;i++){
resultStr+=this.item[i]+ ""
}
return resultStr
}
}
//实现十进制转二进制
function dec2bin(number){
//定义栈对象
var stack=new Stack()
while(number>0){
//获取余数并放入栈中
stack.push(number%2)
//获取整除后的结果并作为下一次的数字
number=Math.floor(number/2)
}
var binString=""
while(!stack.isEmpty()){
//取出栈中的数字
binString+=stack.pop()
}
return binString
}
dec2bin(100)
基于链表实现
队列
了解队列
队列(queue),是一种受限的线性表,先进先出。只允许在表的前端进行删除,在表的后端进行插入。
队列结构的实现
基于数组实现
//封装队列
function Queue(){
this.items=[]
//方法
//1.将元素添加到队列中
Queue.prototype.push=function(element){
this.items.push(element)
}
//2.从队列中删除前端元素
Queue.prototype.dequeue=function(element){
return this.items.shift()
}
//3.查看前端的元素
Queue.prototype.front=function(){
return this.items[0]
}
//4.查看队列是否为空
Queue.prototype.isEmpty=function(){
return this.items.length ==0
}
//5.查看队列中元素的个数
Queue.prototype.size=function(){
return this.items.length
}
//6.toString方法
Queue.prototype.toString=function(){
var resultStr=""
for(var i=0;i<this.items.length;i++){
resultStr+=this.items[i]+""
}
return resultStr
}
}
var queue=new Queue()
queue.push(1)
queue.push(2)
console.log(queue.toString())
思考:实现击鼓传花,几个人围成一圈,开始数数,书到某个数字的人自动淘汰。最后剩下的是哪个位置上的人。
function passName(nameList,num){
//创建一个队列
let queue=new Queue()
for(var i=0;i<nameList.length;i++){
//一次向队列中添加内容
queue.push(nameList[i])
}
while(queue.size()>1){
for(var i=0;i<num -1;i++){
//如果不为num,则先将元素删除,再将元素插入到最后
queue.push(queue.dequeue())
}
queue.dequeue()
}
return queue.front()
}
console.log(passName(['lisa','pengpeng','momo'],4))
优先级队列
优先级队列的特点:
普通的队列插入一个元素,数据会被放在后端。并且需要前面所有的元素都处理完成后才会处理后面的数据。
优先级队列,在插入一个元素时会考虑该数据的优先级,和其他数据的优先级进行比较。比较完成后可以得出这个元素在队列中的正确位置。
优先级队列主要考虑的问题
每个元素不再只是一个数据,包含数据的优先级
在添加方式中,根据优先级放入正确的位置
封装优先级队列
//封装优先级队列
function priorityQueue(){
//在priorityQueue中重新创建了一个类,可以理解为内部类
function QueueElement(element,priority){
this.element=element
this.priority=priority
}
//封装属性
this.itemList=[]
//实现插入方法
priorityQueue.prototype.enqueue=function(element,priority){
//1.创建QueueElement对象
var queue=new QueueElement(element,priority)
//2.判断队列是否为空
if(this.itemList.length ==0){
//为空则直接添加
this.itemList.push(queue)
}else{
var added=false
for(var i=0;i<this.itemList.length;i++){
//优先级大于之前的元素,则直接插入到该元素的位置
if(queue.priority<this.itemList[i].priority){
this.itemList.splice(i,0,queue)
added=true
break
}
}
//如果没有添加
if(!added){
//在最后添加
this.itemList.push(queue)
}
}
}
}
var pq=new priorityQueue()
pq.enqueue('aaa',11)
pq.enqueue('bbb',33)
pq.enqueue('ccc',22)
console.log(pq)