js数据结构中的栈
栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶。咖啡厅内的一摞盘子是现实世界中常见的栈的例子。只能从最上面取盘子,盘子洗净后,也只能摞在这一摞盘子的最上面。栈被称为一种后入先出(LIFO,last-in-first-out)的数据结构。
由于栈具有后入先出的特点,所以任何不在栈顶的元素都无法访问。为了得到栈底的元素,必须先拿掉上面的元素。
对栈的两种主要操作是将一个元素压入栈和将一个元素弹出栈。入栈使用 push() 方法,出栈使用 pop() 方法4
另一个常用的操作是预览栈顶的元素。 pop() 方法虽然可以访问栈顶的元素,但是调用该方法后,栈顶元素也从栈中被永久性地删除了。 peek() 方法则只返回栈顶元素,而不删除它。
为了记录栈顶元素的位置,同时也为了标记哪里可以加入新元素,我们使用变量 top ,当向栈内压入元素时,该变量增大;从栈内弹出元素时,该变量减小。push() 、 pop() 和 peek() 是栈的 3 个主要方法,但是栈还有其他方法和属性。 clear() 方法
清除栈内所有元素, length 属性记录栈内元素的个数。我们还定义了一个 empty 属性,用以表示栈内是否含有元素,不过使用 length 属性也可以达到同样的目的。
栈的实现
/**
* Created by Administrator on 2016/12/9.
*/
function Stack() {
this.dataStore=[];
this.top=0;
this.push=push;
this.pop=pop;
this,peek=peek;
this.length=length;
}
/*当向栈中压入一个新元素时,需要将其保存在数组中变量 top 所对
应的位置,然后将 top 值加 1,让其指向数组中下一个空位置。*/
function push(element) {
this.dataStore[this.top++]=element;
}
//与 push() 方法相反——它返回栈顶元素,同时将变量 top 的值减 1:
function pop() {
return this.dataStore[--this.top];
}
//返回数组的第 top-1 个位置的元素,即栈顶元素:
function peek() {
return this.dataStore[this.top-1];
}//如果对一个空栈调用 peek() 方法,结果为 undefined 。这是因为栈是空的,栈顶没有任何元素。
function length() {
return this.top;
}
function clear() {
this.top=0;
}
实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="Stack.js"></script>
<script>
/********数制转换*********/
/* 可以利用栈将一个数字从一种数制转换成另一种数制。假设想将数字 n 转换为以 b 为基数
的数字,实现转换的算法如下。
(1) 最高位为 n % b,将此位压入栈。
(2) 使用 n/b 代替 n。
(3) 重复步骤 1 和 2,直到 n 等于 0,且没有余数。
(4) 持续将栈内*/
function mulBase(num, base) {
var s = new Stack();
do {
s.push(num % base);
num = Math.floor(num /= base);
} while (num > 0);
var converted = "";
while (s.length() > 0) {
converted += s.pop();
}
return converted;
}
console.log(mulBase(5, 2));
/********回文*********/
/* 回文是指这样一种现象:一个单词、短语或数字,从前往后写和从后往前写都是一样的。
比如,单词“dad”、“racecar”就是回文 */
//是一个利用前面定义的 Stack 类,判断给定字符串是否是回文的程序
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 (word == rword) {
return true;
}
else {
return false;
}
}
var word = "hello";
if (isPalindrome(word)) {
console.log(word + " is a palindrome.");
}
else {
console.log(word + " is not a palindrome.");
}
word = "racecar"
if (isPalindrome(word)) {
console.log(word + " is a palindrome.");
}
else {
console.log(word + " is not a palindrome.");
}
/* 程序的输出为:
hello is not a palindrome.
racecar is a palindrome. */
/********递归演示*********/
//为了演示如何用栈实现递归,考虑一下求阶乘函数的递归定义。首先看看 5 的阶乘是怎么定义的:
function factorial(n) {
if (n === 0) {
return 1;
}
else {
return n * factorial(n-1);
}
}
/*使用栈来模拟计算 5! 的过程,首先将数字从 5 到 1 压入栈,然后使用一个循环,将数字挨
个弹出连乘,就得到了正确的答案:120。*/
function fact(n){
var s = new Stack();
while (n > 1) {
s.push(n--);
}
var product = 1;
while (s.length() > 0) {
product *= s.pop();
}
return product;
}
console.log(factorial(5)); // 显示 120
console.log(fact(5)); // 显示 120
</script>
</head>
<body>
</body>
</html>