栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一段称为栈顶。栈是一种后入先出(LIFO,last-in-first-out)的数据结构。
对栈的两种主要操作是将一个元素压入栈和将一个元素弹出栈。入栈使用 push() 方法,出栈使用 pop() 方法。
另外,pop方法虽然可以访问栈顶元素,但使用该方法后,栈顶元素也被从栈中永久性的删除了,可以使用 peek() 方法只返回栈顶元素而不删除它。
栈的实现
实现一个站,要先确定存储数据的底层数据结构,这里采用数组。
定义 Stark 类的构造函数。
function Stark() {
this.dataStore = []; //使用数组 dataStore 保存栈内元素
this.top = 0; //变量 top 记录栈顶位置
this.push = push; //向栈中压入一个新元素
this.pop = pop; //返回栈顶元素,同时将 top 减 1
this.peek = peek; //返回栈顶元素
}
实现 push() 方法,向栈中压入一个新元素。
function push(element) {
this.dataStore[this.top++] = element;
}
实现 pop() 方法,返回栈顶元素,同时将 top 减 1
function pop() {
return this.dataStore[--this.top];
}
实现 peek() 方法,返回栈顶元素。
function peek() {
return this.dataStore[this.top - 1];
}
其它常用的方法。
function length() {
return this.top;
} // 返回栈内元素个数
function clear() {
this.top = 0;
} // 清空栈
使用 Stark 类
数制间的相互转换 --- 可以利用栈将一个数字从一种数制转换成另一种数制。
假设想要将数字 n 转换为以 b 为基数的数字,实现算法如下:
1. 最高位为 n % b,将此位压入栈。
2. 使用 n/b 代替 n。
3. 重复步骤1和2,直到 n = 0,且没有余数。
4. 持续将栈内元素弹出,直到栈为空,依次将这些元素排列
function nulBase(num, base) {
var s = new Stark();
do {
s.push(num % base);
num = Math.floor(num /= base);
} while (num > 0);
var converted = "";
while (s.length() > 0) {
converted += s.pop();
}
return converted;
}
回文 --- 一个单词、短语、或数字,从前往后写和从后往前写都是一样的。(eg:dad、NaN、1001、22)
使用栈可以轻松判定一个字符串是否是回文。先将字符串按从左到右的顺序压入栈,栈内就保存了一个反转后的字符串,通过持续弹出栈中的每个字母就可以得到一个新字符串,该字符串刚好与原来的字符串相反。只需比较这连个字符串是否相等就可以判断是否是回文。
function isPalindrome(word) {
var s = new Stark();
for (var i = 0; i < word.length; i++) {
s.push(word[i]);
}
var rword = "";
while (s.length() > 0) {
rword += s.pop();
}
if (word == rword) {
return true;
}
else {
return false;
}
}
使用栈模拟递归
function fact(n) {
var s = new Stark();
while (n > 1) {
s.push(n--);
}
var product = 1;
while (s.length() > 0) {
product *= s.pop();
}
return product;
}