目录
一、初识栈结构
数组是一种线性结构,在数组的任意位置可以插入和删除数据。有些情况下,为了实现某些功能,需要限制在任意位置插入删除等操作。栈和队列就是常见的受限的线性结构。
栈(stack),它是一种受限的线性表,后进先出(LIFO)
- 仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,另一端称为栈底。
- LIFO(last in fist out)表示就是后进入的元素,第一个弹出栈空间
- 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素
- 从栈删除一个元素又称作出栈或退栈,它是把栈顶元素删除,使其相邻的元素成为新的栈顶元素
栈结构示意图:
二、函数调用栈
函数之间会互相调用:A调用B,B中调用C,C中调用D。在执行过程中,会将A压入栈,A没有执行完,所以不会弹出栈 ,在A的执行过程中调用了B,会将B压入栈,这时B在栈顶,A在栈底。如果此时B执行完了,B会弹出栈,但是B没有执行完,它调用了C,所以C会入栈,并且在栈顶,而后又调用了D,D又压入到栈顶。所以当前的栈顺序是:栈底A -> B -> C -> D。D执行完后,D弹出栈。C/B/A依次弹出栈。所以有函数调用栈的称呼,就来自于它们内部的实现机制—通过栈来实现。
三、栈结构的实现(基于数组)
先创建一个栈的类,用于封装栈相关的操作
//封装栈类
function Stack(){
//栈中的属性
this.items = []
//栈相关的方法
}
我们创建了一个Stack构造函数,用户创建栈的类。在构造函数中,定义了一个变量,这个变量可以用于保存当前栈对象中所有的元素。这个变量是一个数组类型,我们之后无论是压栈操作还是出栈操作,都是从数组中添加或删除元素。
四、栈常见的操作
push(element) :添加一个新元素到栈顶位置
pop() :移除栈顶元素,同时返回被移除的元素。
peek() :返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)
isEmpty() :如果栈里没有任何元素就返回true,否则返回false.
size() :返回栈里的元素个数。这个方法和数组的length属性很类似
toString() :将栈结构的内容以字符形式返回。
function Stack(){
//栈中的属性
this.items = []
//栈的相关操作
//1.将元素压入栈
Stack.prototype.push = function(element){
return 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.将栈结构的内容以字符形式返回
Stack.prototype.toString = function(){
var resultString = ''
for(var i = 0; i < this.items.length; i++){
resultString += this.items[i] + ' '
}
return resultString
}
}
五、将十进制转成二进制
思路:
//函数:将十进制转化成二进制
function dec2bin(decNumber){
//1.定义栈对象
var stack = new Stack()
//2.循环操作
while (decNumber > 0){
//2.1获取余数,并且放入到栈中
stack.push(decNumber % 2)
//2.2获取整除后的结果,作为下一次运行的数字
decNumber = Math.floor(decNumber / 2)
}
//3.从栈中取出0和1
var binaryString = ''
while(!stack.isEmpty()){
binaryString += stack.pop()
}
return binaryString
}