目录
目录
1.什么是栈:
栈是一种受限线性表
栈的特点为先进后出,后进先出(LIFO:last in first out)。
其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底
2.定义栈结构的两种方式:
定义栈结构我们可以还是用构造函数或者class来定义
在
ES6
(ECMAScript6
)之前,JavaScript
语法中是不支持类的,导致面向对象编程方法无法直接使用,但我们可以通过function来实现模拟出类,而随着JavaScript
的更新,在ES6
出现了中出现class
关键字,可以用于定义类。
①构造函数 function
function Stack(maxSize) {
// 存入栈中的元素
this.items = [];
this.maxSize = maxSize || 0;
// top 栈顶元素的位置
this.top = -1;
}
② class 【类】 constructor——构造函数
//基于数组的栈
class Stack {
constructor() {
this.items = []; //用来保存栈中的数据元素
this.masSize=maxSize||0;
this.top=-1;
}
}
在上面定义栈的两种方式中我们使用数组来模拟栈:栈的数据结构,结构中用于保存数据的变量我们用数组来保存, * 但是你要明白本质上是为 items 申请了一块地址连续的内存空间
问:在设置栈的时候,为什么将栈顶元素设置为-1
空栈的top为-1,因为0是第一个元素,如果top=0,就表示有第一个元素,不为空
3.栈的基本操作:
- push(element):添加一个新元素到栈顶位置;
- pop():移除栈顶的元素,同时返回被移除的元素;
- peek():返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它);
- isEmpty():如果栈里没有任何元素就返回true,否则返回false;
- size():返回栈里的元素个数。这个方法和数组的length属性类似;
- toString():将栈结构的内容以字符串的形式返回
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>02_栈的封装</title>
</head>
<!-- 栈最好封装成为一个类, 在js 中是基于对象的————要写成一个函数 -->
<!-- js 如何基于对象实现面向对象这种特性的 -->
<body>
<script>
// 方法: method 和某一个对象实例有联系
// 函数:function
// 封装栈类
function Stack() {
// 用来保存栈中的数据
this.items = []
// 栈的相关操作
// 1.将元素压入栈
// 方式1: 相当于给对象实例添加方法 这两种方式有什么区别 ??? 第二种更便捷 ??? 为什么
// this.push = function () {
// }
// 方式2: 通过原型 相当于给类添加方法
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] // 这个地方的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.toString = function () {
var resultString = ''
for (var i = 0; i < this.items.length; i++) {
resultString += this.items[i] + '' // += resultString=resultString+this.items[i]
}
return resultString
}
}
// 栈的使用
var s = new Stack()
s.push(20)
s.push(30)
s.push(40)
s.push(50)
s.push(60)
// alert(s)
console.log(s);
s.pop()
s.pop() // 两个pop 之后 删除了 50 60
console.log(s.peek(), '栈顶元素');
console.log(s.isEmpty(), '是否为空');
console.log(s.size(), '元素的个数');
console.log(s.toString(), '转换为字符串');
</script>
</body>
</html>
4.letCode20 有效的括号
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
const stack = []; // 用来保存栈中的数据
for (let i = 0; i < s.length ; i++) { // 遍历字符串的长度
const f = s[i] // 把循环的值赋值给f
if (f === '(' || f === '[' || f === '{') {
stack.push(f) // 当满足上面三种情况的话,将f推入 stack 让左括号入栈
} else {
const l = stack[stack.length - 1]; // 这里得到的是栈顶元素的下标得到它的值的值 因为栈顶没有加入新元素
if ((l === '(' && f === ')') // 如果栈顶元素和入栈元素相同
|| (l === '[' && f === ']')
|| (l === '{' && f === '}')
) {
stack.pop(); // 弹出
} else {
return false
}
}
}
if (stack.length == 0) {
return true
} else {
return false
}
}
5.题解
首先我们遍历字符串s的长度