1. 对栈的操作
栈是一种后入先出(LIFO, last-in-first-out)的数据结构。
对栈的两个主要操作: 一个将元素压入栈,一个将元素弹出栈。入栈使用push()方法,出栈使用pop()方法。
另外常用操作是预览栈顶的元素。pop()方法虽然可以访问栈顶元素,但是,栈顶元素会被删除掉,所以我们需要peek()只返回栈顶元素,而不删除栈顶元素。
为了记录栈顶元素的位置,需要使用变量top。
clear()方法清除栈内所有元素,length()方法记录栈内元素个数,empty是否为空。
2. 栈的实现
我们可以定义Stack类的构造函数
function Stack() {
this.dataStore = []
this.top = 0
}
Stack.prototype.push = function(element) {
this.dataStore[this.top ++] = element
}
Stack.prototype.pop = function(element) {
if(this.top > 0) {
this.top --
}
return this.dataStore.pop()
}
Stack.prototype.peek = function() {
return this.dataStore[this.top - 1]
}
Stack.prototype.length = function() {
return this.top
}
Stack.prototype.clear = function() {
this.dataStore = []
this.top = 0
}
Stack.prototype.empty = function() {
return !!this.top
}
测试Stack类的实现
var s = new Stack();
s.push("David");
s.push("Raymond");
s.push("Bryan");
console.log("length: " + s.length());
console.log(s.peek());
var popped = s.pop();
console.log("The popped element is: " + popped);
console.log(s.peek());
s.push("Cynthia");
console.log(s.peek());
s.clear();
console.log("length: " + s.length());
console.log(s.peek());
s.push("Clayton");
console.log(s.peek());
3. 使用Stack类
3.1 进制间的相互转换
算法如下:
- 最后一位为 n % b,将此位压入栈。
- 使用n / b代替 n。
- 重复步骤1,2。直到 n <= 0,且没有余数。
- 持续将栈的元素弹出,直到为空为止,将这些元素排序,拼接成字符串。
function mulBase(num, base) {
if(num <= 0) {
return num
}
var s = new Stack()
do {
s.push(num % base)
num = Math.floor(num / base)
} while(num > 0)
var converted = ''
while(s.length()) {
converted += s.pop()
}
return converted
}
3.2 回文
回文指这样的一种现象: 'dad', 'racecar',从前往后写和从后往前写都一样。
使用栈可以轻松判断字符串是否是回文。
function isPalindrome(word) {
var s = new Stack()
for(let i = 0; i < word.length; i ++) {
s.push(word[i])
}
var rword = ''
while(s.length()) {
rword += s.pop()
}
return word === rword
}
3.3 递归演示
用栈可以演示模拟递归的过程。
例如5的阶乘: 5! = 5 * 4 * 3 * 2 * 1;
递归函数:
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 product = 1
while(s.length()) {
product *= s.pop()
}
return product
}
3.4 栈可以用来判断一个算术表达式中的括号是否匹配。编写一个函数,该函数接受一个算术表达式作为参数,返回表达式中的括号是否匹配。下面是一个括号不匹配的算术表达式的例子:2.3 + 23 / 12 + (3.14159×0.24。
function check(expression) {
var s = new Stack()
for(let i = 0; i< expression.length; i ++) {
if(expression[i] === '(') {
s.push('(')
}
if(expression[i] === ')') {
if(s.length()) {
s.pop()
} else {
return false
}
}
}
return !s.length()
}