javascript中的栈结构
1.栈的定义
栈是一种和列表类似的数据结构,可以用它来解决很多的编程问题,栈是一种高效的数据结构,因为数据只能在栈的顶端添加或者删除,所以这样的操作很快而且容易实现。
栈是一种特殊的列表,站内的元素只能拖过列表的一端进行访问,这一端陈伟栈顶。一叠盘子是最常见的栈结构,只能从顶部取盘子,洗好的盘子也只能放在顶端。栈被称为后入先出的数据结构。
由于栈具有后入先出的特点,所以任何不在栈顶的元素都无法访问。为了得到栈底的元素,必须拿掉上面的元素。
对栈的操作有将一个元素压入栈和将一个元素弹出栈。把元素压入栈顶使用push()方法,从栈顶弹出元素使用pop()方法。还有一个方法是预览栈顶元素,使用pop()方法虽然可以访问栈顶的元素,但是调用该方法后栈顶的元素将被永久的删除。peek()方法只返回栈顶的元素,而不删除它。
为了记录栈顶元素的位置,同时也为了标记从哪里可以加入新元素,我们使用变量top,当向栈内压入元素是该变量增大,从站内弹出元素时,该变量减小。
pop(),push(),peek()方法是最主要的三个方法,同时定义clear()方法可以清楚栈内所有的元素,length属性定义栈内元素的个数,同时定义一个empty属性标识栈内是否还有元素,不过使用length属性可以达到同样的目的。
栈结构的代码如下:
//使用数组dataStore保存站内元素,构造函数将其初始化为一个空数组。
//变量top定义栈顶的位置,构造时初始化为0,表示栈的起始位置为0
function Stack(){
this.dataStore = [];
this.top = 0;
this.push = push;
this.pop = pop;
this.peek = peek;
this.clear = clear;
this.length = length; //注意++操作符的位置,它放在this.top的后面,这样新入栈的元素就被放在top的当前位置对应的位置,同时top自加1,指向下一个位置
function push(element){
this.dataStore[this.top++] = element;
}
//返回栈顶元素,同时top的位置减1
function pop(){
return this.dataStore[--this.top];
}
//peek()方法返回数组的第top-1个位置的元素,即栈顶元素
function peek(){
return this.dataStore[this.top-1];
}
//将top的值设置0,即清空一个栈
function clear(){
this.top = 0;
}
//返回变量top的值即为栈内元素的个数
function length(){
return this.top;
}
}
使用下面的代码来检验栈结构
var s = new Stack();
s.push("David");
s.push("Baymond");
s.push("Bryan");
document.writeln("length:" + s.length());
document.writeln(s.peek());
var popped = s.pop();
document.writeln("the popped element is:" + popped);
document.writeln(s.peek());
s.push("Cynthia");
document.writeln(s.peek());
s.clear();
document.writeln("length:" + s.length());
document.writeln(s.peek());
s.push("Clayton");
document.writeln(s.peek());
输出如下:
length:3
Bryan
the popped element is:Bryan
Baymond
Cynthia
length:0
undefined
Clayton
2.用栈实现进制转换
可以使用栈将一个数字从一种数制转换成另一种数制,假设想将数字n转换为以b为基数的数字,实现方法如下:
(1)最高位为n%b,将此位压入栈
(2)使用n/b代替n
(3)重复(1),(2)直到n等于0,且没有余数
(4)持续将站内元素弹出,直达栈为空,依次将这些元素排列,就得到转换后的数字的字符串形式
来看下面的代码,如何将数字转换为2进制和8进制
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;
}
var num = 32;
var base = 2;
var newNum = mulBase(num, base);
document.writeln(num + " converted to base " + base + " is " + newNum);
num = 125;
base = 8;
newNum = mulBase(num, base);
document.writeln(num + " converted to base " + base + " is " + newNum);
最后输出的结果如下:
32 converted to base 2 is 100000 125 converted to base 8 is 175
3.用栈判断回文
回文是这样一种现象:一个单词,短语或者数字,从前往后和从后往前写都是一样的。比如单词“dad”,“racecar”就是回文;如果忽略空格和标点符号,下面这个句子也是回文,“A man, a plan, a canal: Panama”,数字1001也是回文。
使用栈可以轻松的判断一个字符是否是回文。我们将拿到的字符串的每个字符按照从左至右的顺序入栈,当所有字符都入栈之后站内就保存了一个反转后的字符串,最后的字符在栈顶,第一个在栈尾。字符串完全压入站内后,通过持续弹出栈中的每个字母就可以的大一个新的字符串,该字符串刚好与原来的字符串顺序相反。我们只要比较这两个字符串即可,如果他们相等就说明这个是一个回文。代码如下:
function isPalindrome(word){
var s = new Stack();
for (var i=0; i<word.length; ++i) {
s.push(word[i]);
}
var reword = "";
while(s.length()>0){
reword += s.pop();
}
if(word == reword){
return true;
}else{
return false;
}
}
var word = "hello";
if(isPalindrome(word)){
document.writeln(word + " is a palindrome.");
}else{
document.writeln(word + " is not a palindrome");
}
word = "racecar";
if(isPalindrome(word)){
document.writeln(word + " is a palindrome.");
}else{
document.writeln(word + " is not a palindrome");
}
输出结果如下:
hello is not a palindrome
racecar is a palindrome.
4.用栈实现递归
递归是一种很常见的算法,使用栈来实现递归是一件很轻松的事情,例如计算阶乘可以使用递归算法,如下:
function factorial(n) {
if (n === 0) {
return 1;
}
else {
return n * factorial(n-1);
}
}
使用栈来模拟阶乘过程,例如:首先将5到1压入栈内,然后使用给一个循环,将数字一次弹出连乘就得到正确的答案,代码如下:
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;
}
document.writeln(fact(5));
结果如下:
120
5.使用栈判断表达式中的括号是否完整
表达式中的{和},(和),[和]必须是匹配的,不然的话表达式就会出现语法错误,使用栈可以判断表达式中的括号是否左右匹配。思路是遇到左括号就入栈,遇到右括号就和当前栈顶元素匹配,如果匹配成功就将栈顶元素出栈,最后判断栈中元素个数,如果是0就代表是完整的,否则就是不完整的。代码如下:
function isMatch(str){
var left = "({[";
var right = ")}]";
var s = new Stack();
var i = 0;
while (str[i]){
//左符号入栈
if(left.indexOf(str[i])>-1){
s.push(str[i])
}
//遇到右括号
else if( right.indexOf(str[i])>-1 && right.indexOf( str[i] ) == left.indexOf( s.peek()) ){
s.pop();
}
i++
}
// document.writeln( s.peek() );
if(s.length() == 0){
document.writeln(str + " is match success");
}else{
document.writeln(str + " is not match");
}
}
isMatch("2.3 + {23 / 12 + (3.14159×0.24)");
javascript中的栈结构的更多相关文章
- JavaScript中的分支结构
说到JavaScript中的分支结构,我们就不得不提到流程控制这个词,我们所有的程序都是由数据和算法组成的.程序=数据+算法通常我们所说的算法都可以通过"顺序","分支& ...
- javascript中的栈、队列。
javascript中的栈.队列 栈方法 栈是一种LIFO(后进先出)的数据结构,在js中实现只需用到2个函数 push() 接受参数并将其放置 ...
- javascript中的队列结构
1.概念 队列和栈结构不同,栈是一种后进先出的结构,而队列是一种先进先出的结构.队列也是一种表结构,不同的是队列只能在队尾插入元素,在队首删除元素,可以将队列想象成一个在超时等待排队付钱的队伍,或者在 ...
- JavaScript中的栈内存和堆内存
首先JavaScript中的变量分为基本类型和引用类型.基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象. 1.基本类型 基本类型有Undefined.Null.Boo ...
- javascript中的链表结构—从链表中删除元素
1.概念 上一个博文我们讲到链表,其中有一个方法remove()是暂时注释的,这个方法有点复杂,需要添加一个Previous()方法找到要删除的元素的前一个节点,这一个博文我们来分析一下这个remov ...
- javascript中的链表结构
1.定义 很多编程语言中数组的长度是固定的,就是定义数组的时候需要定义数组的长度,所以当数组已经被数据填满的时候,需要再加入新的元素就很困难.只能说在部分变成语言中会有这种情况,在javascript ...
- javascript中的表结构
列表是一种常见的数据结构,通常列表是一族有徐的数据,列表中的数据项称为元素.在javascript中列表中的数据可以是任意类型的,列表中可以保存多少元素没有事先限定,实际使用时元素的数量只收到程序内内 ...
- Javascript中的各结构的嵌套和函数
各位朋友大家好,上周更新给大家分享了JavaScript的入门知识及各种常用结构的用法,那么,本次更新博主就跟大家更深入的聊一聊JS各结构的嵌套用法,及JS中及其常用的一种结构——函数.以下为函数和循 ...
- javascript中的链表结构—双向链表
1.概念 上一个文章里我们已经了解到链表结构,链表的特点是长度不固定,不用担心插入新元素的时候新增位置的问题.插入一个元素的时候,只要找到插入点就可以了,不需要整体移动整个结构. 这里我们了解一下双向 ...
随机推荐
- javascript --- 词法分析
JavaScript代码自上而下执行,但是在js代码执行前,会首先进行词法分析,所以事实上,js运行要分为词法分析和执行两个阶段. 词法分析主要分为三步: 第一步: 分析形参: 第二步: 分析变量声明 ...
- javascript数组浅谈2
上次说了数组元素的增删,的这次说说数组的一些操作方法 join()方法: ,,] arr.join("_") //1_2_3 join方法会返回一个由数组中每个值的字符串形式拼接而 ...
- Sharepoint 2013 列表使用JS Link
使用JS Link可以向Sharepoint List注册脚本,重写Field模板,使得对于符合条件的字段改变格式和样式.但是有一个问题是,页面postback的话,JS不会被触发,不知道怎么解,有知 ...
- 配置SharePoint使用ADFS
1. 如果网站应用程序没有使用声明式验证 $wpp = Get-SPWebApplication <URL> $wpp.UseClaimsAuthentication = 1 $wpp.U ...
- 如何在Eclipse卸载之前添加的android 的 ADT
Android开发环境配置中,怎么卸载ADT? 在Android开发环境配置中,可能会遇到很多问题,其中ADT安装失败需要卸载,怎么卸载呢?下面讲一种方法,希望能够对你有所帮助. 我采用的是Eclip ...
- 【读书笔记】iOS-NSPredicate
一,Cocoa提供了一个名为NSPredicate的类,它用于指定过滤器的条件.可以创建NSPredicate对象,通过该对象准确地描述所需的条件,对每个对象通过谓词进行筛选,判断它们是否与条件相匹配 ...
- iOS开发之网络编程--小文件下载
文件下载方式: 如果下载的文件比较小,下载方式: 直接用NSData的 +(id)dataWithContentsOfURL:(NSURL*)url; 利用NSURLConnection发送一个HTT ...
- Win7下:编译器错误信息: CS0016: 未能写入输出文件
错误如下: "/"应用程序中的服务器错误. 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码. 编译器错误消息: CS ...
- Effective Java 36 Consistently use the Override annotation
Principle Use the Override annotation on every method declaration that you believe to override a sup ...
- 集线器hub、交换机switch、路由器router 的区别
原文链接:http://blog.csdn.net/thq0201/article/details/7782319 首先说HUB,也就是集线器.它的作用可以简单的理解为将一些机器连接起来组成一个局域网 ...