学过汇编的朋友肯定觉得它的堆栈操作指令很好用吧:
push ax ;ax入栈 push bx ;bx入栈 pop bx ;bx出栈 pop ax ;ax出栈
相比之下,C的堆栈操作让人有时被搞得一头雾水,至少我当时在学数据结构的时候就有些头晕,但当学到汇编时,才有些醒悟了,如果你不知道堆栈是什么,那么我就简单介绍一下:堆栈就像一个箱子,你往里面放东西,先放进去的东西在最底下,而最后放进去的东西在最顶上,有点类似是把东西叠起来的方式.堆栈的操作必须遵照"先进后出,后进先出"的原则,也就是你最后被放进的东西可以最先被取出,最先放进的东西只能在最后被取出.注意我一开始举的例子,ax最先被压入堆栈,所以它在最后才能出栈.
这样说有些抽像是吧,那举个例子吧,用js语言来描述吧:
var a=[1,2,3,4,5] //假设我们现在认为a是一个堆栈(堆栈最简单的构成方式就是用一个一维数组)
如果我们使用堆栈的操作方法压入一个数据,比如是6,那么现在的堆栈是这样的:a=[1,2,3,4,5,6],这样数据就入栈了,继续这样操作我们再压了更多数据,现在堆栈变成这样了:a=[1,2,3,4,5,6,7,8,9],那么,如果现在要出栈的话,就必须先把9弹出,然后再把8弹出,如此类推.假设我们要取数据6,那我们就必须把它上面的数据7~9依次弹出去,这样6就成了栈顶的元素,才能正常出栈. phperz.com
有人会提出疑问,为什么我们不用a[5]来读取数据6,呵呵,很聪明的问题,我现在来回答你,的确,你可以用这样的访法读得你要的数据,不过,这样一来,就不是我们所说的堆栈操作了,想想堆栈操作的定义和它的操作原则,入栈时,数据存放在栈的最顶端,然后顶部指针递增,指向更高一个空的数据单元(忘了介绍头指针了,也就是指向栈顶数据的数组下标+1,指向堆栈中顶部的一个空闲单元,数据入栈时就存入这个单元中,然后头指针递增1,指向更高一个空闲单元),而出栈则相反,首先把顶部的数据弹出去,然后清空这个单元,头指针递减1,这样就释放掉了不需要的资源.操作的原则:先进后出,后进先出.现在来比较一下,用下标去直接访问数组,并不满足堆栈的定义和操作原则.现在清楚了吧,如果你想用堆栈,就别想着下标,尽管我们用数组来模拟堆栈,但是,堆栈并不等于数组.相信学过C的朋友知道,数组只是最简单的模拟堆栈的形式,更多的,可以用链表去实现堆栈,不过js没那功能,所以就用数组吧!
明白了堆栈的原理,就开始写代码模拟堆栈吧,这里我用函数及其方法来实现,关于构造函数以及函数的方法的使用在javascript权威指南上有介绍,推荐大家去看看,记得网上流传着一个日历脚本,其实现也是用构造函数来完成的,因为那时对Array支持不够完善吧,所以用构造函数来实现数组,这是我猜想的,如果说错了大家见谅.好了,直接放代码了,有注释的,运行一下你就明白了.<!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> www~phperz~com <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>模拟堆栈</title> </head> <body> <script type="text/javascript"> <!-- function stack(){ if(this.top==undefined){ //初始化堆栈的顶部指针和数据存放域 this.top=0; this.unit=new Array(); } this.push=function(pushvalue){ //定义压入堆栈的方法 this.unit[this.top]=pushvalue; this.top+=1; } this.readAllElements=function(){ //定义读取所有数据的方法 if(this.top==0){ alert("当前栈空,无法读取数据"); return(""); } var count=0; var outStr=""; for(count=0;count<this.top;count++){ outStr+=this.unit[count]+","; } return(outStr); www.phperz.com } this.pop=function(){ //定义弹出堆栈的方法 if(this.top==0){ alert("当前栈空,无法弹出数据"); return(""); } var popTo=this.unit[this.top-1]; this.top--; return(popTo); /* 从堆栈弹出数据,顶部指针减一,不过这里没有做到资源的释放,也 就是说数据仍然存在于this.unit的数组中,只不过无法访问罢了。目前 我也没想到好的办法解决。*/ } } //使用构造函数创建一个新堆栈 var raino = new stack(); //********************************************************* //这种形式可能比下面的表单式更容易看懂,把注释去掉就行了。 //然后把下面的表单式的html注释掉就行了,看你喜好了 //用push()方法将实验数据压入堆栈中,这里压入三组数据 //raino.push("第一个数据被压入堆栈"); //raino.push("第二个数据被压入堆栈"); //raino.push("第三个数据被压入堆栈"); www.phperz.com //用readAllElements()方法读取堆栈中的所有数据 //raino.readAllElements(); //用pop()方法来弹出堆栈的顶部数据 //var getValue; //getValue=raino.pop(); //alert("从堆栈中弹出数据顶部的数据是:"+getValue); //********************************************************* //--> </script> <input type="text" id="pushtostack" value="在此输入入栈数据"/> <input type="button" onclick="raino.push(pushtostack.value)" value="压入堆栈"/> <br /><br /> <hr /> <input type="button" value="读取堆栈中的所有数据" onclick="getstackinfo.innerText=raino.readAllElements()"/><br /><br /> <div id="getstackinfo" style="width:300px;height:240px;border:1px solid #000;"></div> <br /><br /> <hr /> phperz.com <input type="text" name="popfromstack" /> <input type="button" onclick="popfromstack.value=raino.pop()" value="从堆栈弹出"/> <br /><br /> </body> </html>
|