1.首先,什么是栈?
栈是一种线性逻辑结构
。只支持入栈和出栈操作,遵循后进先出
的原则(FILO)。
2.js描述栈
/*栈需要的操作:
* 1.入栈 push()
* 2.出栈 pop():该方法将栈顶元素永久删除
* 3.预览栈顶元素 peek():该方法只是返回栈顶元素,不会删除栈顶元素。
* 4.记录栈顶位置的变量 top:(1)当元素入栈时,该变量增大;(2)元素出栈时,该变量减小。
* 5.清空栈的方法 clear()
* 6.表示栈中元素个数的变量length
* 7.查看栈是否为空的方法 isEmpty()
*
* 栈的实现:
* js中我们采用了数组来模拟栈结构的实现。
*/
// 栈类
function Stack() {
this.dataSource = [];
this.top = 0;
this.length = length;
this.push = push;
this.pop = pop;
this.peek = peek;
this.clear = clear;
this.isEmpty = isEmpty;
}
function push(data) {
this.dataSource[this.top++] = data;
}
function pop() { // 去元素的时候,从栈顶去元素,这里从数组的最后一位去取元素
return this.dataSource[--this.top] ;
}
function clear() {
// 这里将top值设置为0,即可清空栈中元素了。因为栈中元素的获取是从top变量而来的。
this.top = 0;
}
function peek() {
// 因为top始终指向的是,栈中下一个空位置,所以,减一
return this.dataSource[this.top - 1];
}
function length() {
return this.top;
}
function isEmpty() {
return !!this.top;
}
const s = new Stack();
3.栈的应用
- 进制转换
- 回文判断
- 括号匹配
/*
*栈的应用:
*1.进制转换
*2.判断字符串是否为回文
* 3.括号匹配
*/
// 1.进制转换
function mulBase(data, base) {
const s = new Stack();
do{ // 这里处理了data为0的情况
s.push( String(data % base) );
data = Math.floor(data / base);
} while(data > 0);
let converted = '';
do {
converted += s.pop();
} while (s.top > 0);
return converted;
}
// 2.判断回文
// 为什么可以用栈呢?因为回文的判断就是正向和反向是否一致就行,而栈的存取方式正好合适
function isPalindrome(data) {
const stringData = String(data),
s = new Stack();
[...stringData].forEach(ele => {
s.push(ele);
});
return [...stringData].every(ele => ele === s.pop());
}
// 3.括号匹配
// 算术表达式: 12.3 + 23 / 12 + (3.14 * 14 返回括号缺失的位置
function parenthesesMatching(data) {
const stringData = String(data);
const s = new Stack();
for (let i = 0;i < stringData.length;i++) {
const str = stringData.charAt(i);
if (str === '(') { // 左括号
s.push(str);
}
if (str === ')') { // 遇到右括号,则栈顶元素,出栈
if(s.pop() !== '(') return false; // 出栈的元素,如果不是左括号,则false啦
}
}
return s.length() === 0;
}