开启掘金成长之旅!这是我参与「掘金日新计划 12 月更文挑战」的第 2 天,点击查看活动详情
最近在学习 Javascript 数据结构与算法相关知识,数据结构与算法对程序员来说就像是内功心法,只有不断修炼自己的内功,才能从容不迫的应对市场上各种让人应接不暇的框架,达到以不变应万变。学习数据结构与算法的过程中不仅要能看懂更要多写多练,今天就来手写下栈数据结构。
栈数据结构
栈是一种遵从后进先出原则的有序集合。新添加或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底。
基于数组实现的栈
class StackArray<T> {
private items: T[]; // 定义私有属性
constructor() {
this.items = [];
}
// 入栈
push(element: T) {
this.items.push(element);
}
// 出栈
pop() {
return this.items.pop();
}
// 查看栈顶元素
peek() {
return this.items[this.size() - 1];
}
// 检查栈是否为空
isEmpty() {
return this.size() === 0;
}
// 清空栈
clear() {
this.items = [];
}
// 栈大小
size() {
return this.items.length;
}
toString() {
return this.items.toString();
}
}
利用数组的 push,pop 实现一个栈结构还是很容易的
基于对象实现的栈
这里为什么使用对象来保存栈中元素?
因为在使用数组时,大部分方法的时间复杂度是 O(n)。并且数组是元素的一个有序集合,为了保证元素排列有序,它会占用更多的内存空间。
class Stack<T> {
private count: number;
private items: Record<number, T>;
constructor() {
this.count = 0; // 用于记录栈大小
this.items = {};
}
push(element: T) {
this.items[this.count] = element;
this.count++;
}
pop() {
if (this.isEmpty()) {
return undefined;
}
this.count--;
const result = this.items[this.count];
delete this.items[this.count];
return result;
}
peek() {
if (this.isEmpty()) {
return undefined;
}
return this.items[this.count - 1];
}
isEmpty() {
return this.count === 0;
}
clear() {
this.items = {};
this.count = 0;
}
size() {
return this.count;
}
toString() {
if (this.isEmpty()) {
return "";
}
let objString = `${this.items[0]}`;
for (let i = 1; i < this.count; i++) {
objString = `${objString},${this.items[i]}`;
}
return objString;
}
}
使用场景
所有后进先出的场景 函数调用堆栈
leetcode 练习题:20 有效的括号
题目描述:
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function (s) {
const arr = [];
for (let i = 0; i < s.length; i++) {
if (["(", "[", "{"].includes(s[i])) {
arr.push(s[i]); // 左括号入栈
} else if (
(s[i] === ")" && arr[arr.length - 1] === "(") ||
(s[i] === "]" && arr[arr.length - 1] === "[") ||
(s[i] === "}" && arr[arr.length - 1] === "{")
) {
arr.pop(); // 能闭合就出栈
} else {
return false;
}
}
return arr.length === 0;
};
解题思路是利用栈后进先出的特点,左括号入栈,如果右括号与栈顶左括号闭合就出栈,如果都能闭合那栈最后一定为空。
栈数据结构还是比较简单 通俗易懂的,下一篇介绍用typescript实现队列数据结构