前言 今天讲解的是数据结构中的 "栈",
栈的数据结构
栈遵循的是一个先进后出的有序集合,新添加的元素和待删除的元素都保存在同一个端,我们通常叫栈顶
,另一端叫栈底
。新添加的元素都在栈顶
。
行李堆叠:在旅行中,我们可能会把行李逐渐堆叠起来。最后放入的行李在需要取出时通常会先取出,类似于栈的行为。
- 我们将创建一个类来表示栈。简单地从创建一个 stack.js 文件并声明 Stack 类开始。
js
class Stack {
constructor() {
this.items = [];
this.count = 0
}
}
创建一个stack类,创建一个数组, 数组可以进行任何操作;
- 我们需要为栈添加以下方法
push()
: 添加一个新元素到栈顶。pop()
: 移除栈顶的元素,同时返回被移除的元素。peek()
: 返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它)。isEmpty()
: 如果栈里没有任何元素就返回 true,否则返回 false。clear()
: 移除栈里的所有元素。size()
: 返回栈里的元素个数。该方法和数组的 length 属性很类似。toString()
: 打印栈内容
isEmpty()
: 如果栈里没有任何元素就返回 true,否则返回 false。
js
isEmpty() {
return this.count === 0;
}
push()
添加一个新元素到栈顶。
js
push(element) {
this.items[this.count] = element; // 存放到栈顶
this[count]++; // 栈大小+1
}
pop()
: 移除栈顶的元素,同时返回被移除的元素。
js
pop() {
if (this.isEmpty()) { // 删除前判断是否为空
return undefined;
}
const result = this.item[this.count]; // 取栈顶元素
delete this.item[this.count]; // 删除栈顶
this.count--; // 栈大小-1
return result; // 返回 栈顶元素
}
其他方法也类似,主要是对数组的操作,在这里挑了几个来做例子
封装完成的栈
stack.js
js
const _items = Symbol('_stackItems');
const _count = Symbol('_stackCount');
class Stack {
constructor() {
this[_items] = {};
this[_count] = 0;
}
push(element) {
this[_items][this[_count]] = element;
this[_count]++;
}
pop() {
if (this.isEmpty()) {
return undefined;
}
const result = this[_items][this[_count]];
delete this[_items][this[_count]];
this[_count]--;
return result;
}
peek() {
return this[_items][this[_count]];
}
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;
}
}
export default Stack;
这里用了Symbol
来声明属性(不可变属性),用来保护栈内容不被破坏,(正常开发者做库之类的开源插件,大家会在变量前加一个下划线_
,来表示私有变量;但是不保证某些开发者或者新人,去改动_
私有变量,这种约定式并不安全) 用Symbol
可以很好的避免这个问题(还是有方法能够破坏,并不代表属性永远不会受到破坏,只是一种防范的手段)
- 测试:
js
const stack = new Stack();
console.log(stack);
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
// 2 删除栈一个元素
stack.pop();
// 3 查询结果
console.log(stack.peek());
console.log(stack.size());
console.log(stack.isEmpty());
console.log(stack.size());
console.log(stack.isEmpty());
console.log(stack.toString());
console.log(stack.clear());