目录
1.栈的讲解
1.1 栈的入门
栈就是和列表类似的一种数据结构,只能在栈顶添加或删除,后入先出,入栈使用push() 方法,pop()方法虽然可以访问栈顶的元素,但是调用该方法后,栈顶元素也从栈中被永久性地删除了。peek()方法则只返回栈顶元素,而不删除它。clear() 方法清除栈内所有元素,length属性记录栈内元素的个数。我们还定义了一个empty属性,用以表示栈内是否含有元素,不过使用length 属性也可以达到同样的目的。
1.2 栈的实现
Stack.js
function Stack() {
//用来保存栈内元素
this.dataStore=[];
//压栈
this.push=function (element) {
this.dataStore[this.dataStore.length]=element;
}
//出栈(出栈顶数据,先入后出)
this.pop=function(){
if(this.dataStore.length<1)
return null;
//取得最后的数据
var buffer = this.dataStore[this.dataStore.length-1];
//把最后的数据置空
this.dataStore[this.dataStore.length-1]=null;
//改变数组的长度
this.dataStore.length--;
//返回数据
return buffer;
}
//浏览栈顶数据
this.peek=function () {
//获得数组的长度
var length = this.dataStore.length;
return this.dataStore[length-1];
}
//获取栈的长度
this.length = function () {
return this.dataStore.length;
}
//清空栈内数据
this.clear=function () {
delete this.dataStore;
this.dataStore=[];
}
//遍历栈内数组
this.forEach=function (call) {
//1,获得数组的长度
var length = this.dataStore.length;
//2,遍历数据
for(var i=length-1;i>=0;i--){
// var item= this.dataStore[i];
call(this.dataStore[i]);
}
}
}
栈的应用如下:
2. 回文数
回文: 一个单词、短语或数字,从前往后写和从后往前写都是一样的。比如,单词“dad”、“racecar”就是回文;如果忽略空格和 标点符号,下面这个句子也是回文,“A man, a plan, a canal: Panama”;数字1001 也是回文。
思路:使用栈,可以轻松判断一个字符串是否是回文。我们将拿到的字符串的每个字符按从左至右的顺序压入栈。当字符串中的 字符都入栈后,栈内就保存了一个反转后的字符串,最后的字符在栈顶,第一个字符在栈底。
<script src="Stack.js"></script>
<script>
function isPalindrome(words) {
//1,创建栈对象
var stack = new Stack();
//2,获得字符串的长度
var length = words.length;
//3,遍历当前的字符串和压栈,word[i]为本身值,data为压入栈后的逆序值
for(var i=0;i<length;i++){
stack.push(words[i]);
}
//输出打印
var data='';
stack.forEach(function (item) {
data=data+item;
})
//如果当前的文字相等,就返回真
if(words==data){
return true;
}else{
return false;
}
}
//控制台输出打印
console.log(isPalindrome('abaaba'));
</script>
3. 进制转换
进制转换:利用栈将一个数字从一种数制转换成另一种数制。
思路: 将数字n转换为以b 为基数的数字,算法如下:
- 最高位为n % b,将此位压入栈。
- 使用n/b 代替n。
- 重复步骤1 和2,直到n 等于0,且没有余数。
- 持续将栈内元素弹出,直到栈为空,依次将这些元素排列,就得到转换后数字的字符串形式。
<script src="Stack.js"></script>
</head>
<body>
</body>
<script>
function Base(num,base) {
//创建一个栈
var stack=new Stack();
while(num>0){
var buffer=num%base;
//入栈
stack.push(buffer);
//向下取整
num=Math.floor(num/base);
}
//通过return取出栈内元素,得到二进制(通过栈的方法取出,得到逆序值)
var buffer="";
stack.forEach(function (item) {
buffer=buffer+item;
})
return buffer;
}
console.log(Base(42,2));
</script>
4. 递归
阶乘: 看50 的阶乘是怎么定义的: 5! = 5×4×3×2×1 = 120
思路: 递归即是程序在执行过程中不断调用自身的编程技巧
<script src="Stack.js"></script>
<script>
function fact(number) {
//1,创建栈
var stack = new Stack();
while(number>0){
stack.push(number);
number--;
}
var data = 1;
//对当前的数据进行遍历,item相当于上面的number
stack.forEach(function (item) {
data = data*item;
})
return data;
}
console.log(fact(50));
</script>
5. 佩兹糖果盒
题: 现实生活中栈的一个例子是佩兹糖果盒。想象一下你有一盒佩兹糖果,里面塞满了红色、黄色和白色的糖果,但是你不喜 欢黄色的糖果。使用栈(有可能用到多个栈)写一段程序,在不改变盒内其他糖果叠放顺序的基础上,将黄色糖果移出。
思路:从放糖果的栈(stack)中,将不喜欢的糖果放在一个栈(getColorStack)里,将其他糖果放入一个栈(setColorAtack),最后取完糖 果后,将盛装其他糖果的栈(setColorAtack)中的糖果逐个将其放入原来的栈(stack)中,其位置将不会变化。
<script src="Stack.js"></script>
<script>
//创建新栈
var box = new Stack();
var sugars=['red','white','yellow'];
for(var i=0;i<10;i++){
//随机获得 0 ,1 ,2
var index = Math.floor(Math.random()*3);
//糖果入栈
box.push(sugars[index]);
}
//显示糖的顺序
box.forEach(function(sugar){
console.log(sugar);
})
//创建新栈暂时装糖
var buffer = new Stack();
//将不是黄色糖果的糖果入栈
box.forEach(function(sugar){
if(sugar!='yellow'){
buffer.push(sugar);
}
})
//清空以前的糖盒
box.clear();
//遍历缓存糖盒,将buffer栈里的糖果移到box里
buffer.forEach(function(sugar){
box.push(sugar);
})
console.log("************************");
//显示糖盒里面的糖
box.forEach(function(sugar){
console.log(sugar);
})
</script>
6. 括号是否匹配
<script src="Stack.js"></script>
<script>
// 思路:读取算术表达式,遇到左括号‘{’、‘[’、'('压入栈,
// 栈的特点是后入先出,所以当遇到右括号‘}’、‘]’、')'
// 的时候,取出栈顶元素,是否满足读取的右括号,栈顶是与之相
// 匹配的左括号。最后判断栈是否为空,为空证明该表达式没有问
// 题,否则则说明这个表达式存在括号不匹配问题。
function matchBracket(expression) {
//1,创建栈对象
var stack = new Stack();
//2,把字符串分解为数组
var eles = expression.split('');
for (var i = 0; i < eles.length; i++) {
var ele = eles[i];
//indexOf() 方法可返回某个指定的字
// 符串值在字符串中首次出现的位置。
if (['{', '[', '('].indexOf(ele) !== -1) {
stack.push(ele);
} else {
//浏览栈顶元素
var topEle = stack.peek();
switch (ele) {
case '}':
if (topEle === '{') {
stack.pop();
break;
}
return i;
case ']':
if (topEle === '[') {
stack.pop();
break;
}
return i;
case ')':
if (topEle === '(') {
stack.pop();
break;
}
return i;
default: break;
}
}
};
if (stack.length()) {
return expression.length+1;
}
return -1;
console.log(matchBracket('2.3 + 23 / 12 + {(3.14)]159×0.24'));
// 返回30.
</script>