一、栈
1、认识栈
栈是一种常见的数据结构 栈(stack),它是一种受限的线性表,先进后出【后进先出】 数组是一种常见的线性结构,并且可以在任意位置插入和删除数据 但是有时候,我们想实现某一个功能,必须对这种任意性加以限制 而栈和队列就是常见的受限制的线性结构 其限制是仅允许表的一端进行插入和删除元素,这一端被称为栈顶,相对的,把另一端称为栈底。 LIFO(last in first out)表示后进入的元素第一个弹出栈空间,类似于自助餐托盘,最后放上去的托盘,往往先把它拿出去使用。 【只能在顶部插入或删除元素】 向一个栈插入新的元素称为进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之称为新的栈顶元素 从一个栈删除元素又称为出栈或退栈,他是把栈顶元素删除掉,使其相邻的元素称为新的栈顶元素
栈示意图
函数调用栈
(示意图)
//函数调用栈
function fn1(){
fn2()
}
function fn2(){
fn3()
}
function fn3(){
console.log('ok')
}
fn1(); //先是执行到这里的时候,调用fn1函数,将这个函数压入栈,fn1函数执行的时候,调用fn2函数,然后fn2函数入栈,fn2函数在执行的时候调用了fn3函数,将fn3函数入栈,fn3函数执行完毕之后,便出栈【这时fn2就是栈顶】,然后fn2出栈,最后fn1出栈。
练习题
2、栈的封装
//js中是没有栈结构的,想要使用就要自己封装
//实现栈结构的方式 1、基于数组实现 2、基于链表实现
//在这里我们基于数组实现栈的封装
/**
* 栈常见有哪些操作呢?
* push(element):添加一个新元素到栈顶位置.
* pop():移除栈顶的元素,同时返回被移除的元素。
* peek():返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)
* isEmpty():如果栈里没有任何元素就返回true,否则返回false。
* size():返回栈里的元素个数。这个方法和数组的length属性很类似。
* */
class Stack {
// #items;//为提高安全性,在前面加上'#'表示私有字段 ,我们直接stack.#item就会报错
constructor() {
this.items = [];
}
//push(element):添加一个新元素到栈顶位置.
push(element) {
this.items.push(element)
}
//pop():移除栈顶的元素,同时返回被移除的元素。
pop() {
return this.items.pop()
}
//peek():返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)
peek() {
// return this.item[this.item.length-1]
return this.items.at(-1);//也可以实现上面操作
}
//isEmpty():如果栈里没有任何元素就返回true,否则返回false。
isEmpty() {
return this.items.length === 0
}
//size():返回栈里的元素个数。这个方法和数组的length属性很类似。
size() {
return this.items.length
}
clear() {
this.items = []
}
}
let stack = new Stack();
//操作的是对象的item属性上的【数组】
stack.push('qwe')
stack.push('rty')
stack.push('uio')
stack.push('plm')
console.log(stack.items);//['qwe', 'rty', 'uio', 'plm']
stack.pop();//将对象上的item数组,栈顶的一个元素弹出栈
console.log(stack.items)//['qwe', 'rty', 'uio']
console.log(stack.peek());//'uio'
console.log(stack.isEmpty());//false
console.log(stack.size());//3
3、栈的应用(基于上面封装的栈)
//栈的应用
//十进制转成二进制
function dec2bin(tenNum){
let stack1=new Stack();
let twoStr='';
while (tenNum>0){
stack1.push(tenNum%2);
tenNum=Math.floor(tenNum/2);
}
while (stack1.size()){
twoStr+=stack1.pop();
}
return twoStr
}
console.log(dec2bin(1000));//1111101000
//十进制转任意进制
function dec2bin(tenNum,base){
let stack1=new Stack();
let twoStr='';
let s='0123456789ABCDEF';
while (tenNum>0){
stack1.push(tenNum%base);
tenNum=Math.floor(tenNum/base);
}
while (stack1.size()){
twoStr+=s[stack1.pop()];
}
return twoStr
}
console.log(dec