栈的概述
- 栈是与列表类似的数据结构.
- 是一种高效的数据结构, 因为数据只能在栈顶添加或删除, 这样的操作很快且易实现.
- 栈的使用在开发过程中很常见
- 栈的特点: 后入先出(LIFO, last-in-first-out)
栈的操作概述
由于栈具有后入先出的特点, 所以任何不在栈顶的元素都无法访问, 若想得到栈底的元素, 必须拿掉上面的元素
对栈的操作主要有三个:
- 入栈push()
- 出栈pop()–>栈顶元素从栈中移除
- 预览栈顶元素peek()–>只返回栈顶元素, 不移除
为了标记栈顶元素的位置, 同时也标记可以加入元素的位置, 使用变量top进行记录栈顶位置. 入栈时, top变大; 出栈时, top变小.
其他操作:
- clear() 清除栈内所有元素
- length属性 返回栈内元素个数(栈的长度)
- empty属性 标记栈是否为空(true为空, false非空)
栈的实现
1. 定义Stack类的构造函数
function Stack() {
this.dataStore = []; //使用数组存储栈内元素
this.top = 0;
this.push = push; //入栈
this.pop = pop; //出栈
this.peek = peek; //预览栈顶元素
this.clear = clear; //清除栈内所有元素
this.length = length;
this.empty = empty;
}
2.栈内方法的实现
function push(element) {
this.dataStore[this.top++] = element;
}
function pop() {
return this.dataStore[--this.top];
}
function peek() {
return this.dataStore[this.top - 1];
}
function length() {
return this.top;
}
function clear() {
this.top = 0;
}
function empty() {
if(this.top) {
return true;
}
return false;
}
3.栈的使用场景
1.数制间的相互转换(数字n转换为以b为基数的相应数字)
步骤:
- 最高位 n%b, 操作后压入栈
- n = n/b(取整)
- 重复步骤1, 2, 直至n等于0, 且没有余数
- 持续将栈内元素弹出, 并将元素依次排列
注意: 此算法仅针对2~9为基数的情况
示例代码:
function mulBase(n, b) {
var s = new Stack();
do {
s.push(n%b);
n = Math.floor(n/=b);
}while(n>0);
var coverted = '';
while(s.length()>0) {
converted += s.pop();
}
return converted;//相应进制对应的数
}
2. 回文判断(前->后, 后->前排列相同的字符串或数字)
使用栈可以轻松判断一个字符串是否是回文
步骤: 入栈后出栈的字符序列与原文字一致即为回文
实现:
function isPalindrome(word) {
var s = new Stack();
for(var i = 0; i < word.length; i++) {
s.push(word[i]);//字符入栈
}
var rword = '';
while(s.length()>0) {
rword += s.pop();//字符出栈
}
if(rword == word) {//判断
return true;
}
return false;
}
阶乘(递归):
n的阶乘的函数:
function factorial(n) {
if(n === 0) {
return 1;
}else{
return n*factorial(n-1);
}
}
使用栈:
function fact(n) {
var s = new Stack();
while(n>1) {
s.push(n--);
}
var prod = 1;
while(s.length() > 0) {
prod *= s.pop();
}
return prod;
}