怎么理解堆栈指针(Stack Pointer)

 如果的堆栈的实现是往上长的(就是说往顶的方向长,其实质是栈底是定死的不能动,入栈的东西只能不断往上叠,这就像在书桌上放书一样,桌底是定死的,所以书只能一本一本地往上堆,往上长),计算机内部的堆栈的实现采取的就是这种模式,所以就得“先修改指针,然后插入数 据,出栈时刚好相反”,因为堆栈指针指向的总是栈顶元素,栈底不能动,所以数据入栈前要先修改指针使它指向新的空余空间然后再把数据存进去,出栈的时候 自然相反,可以联系上面举的放书的例子。 

      然而,如果堆栈的实现是往下长的(就是说每压一个元素入栈,栈底就自动下移一个元素的位置,其实质就是这种堆栈模型是一个“无底洞”型), 这个时候,栈顶就变成了定死的,就可以先压入元素,然后再修改指针。因为栈底是无限的,压入一个元素,新的元素就取代先前的栈顶元素占据栈顶 的位置,那么先前的指向栈顶元素的指针这个时候就该修改让它指向这个新的栈顶元素了。 

       下面就是对“无底洞”型堆栈的一种实现的描述: 
压栈(入栈):将对象或者数据压入栈中,更新栈顶指针,使其指向最后入栈的对象或   数据。 
弹栈(出栈):返回栈顶指向的对象或数据,并从栈中删除该对象或数据,更新栈顶。 

       话说回来,计算机内部肯定选第一种模型,不会选第二种,因为第二种模型,每压入一个新的元素,都需要把之前堆栈里的所有元素整体下移动一个元素的 位置,腾出栈顶元素的位置让新的元素进来,这种平移可是一笔不小的开销。但是并不是说“无底洞”模型就没办法实现了,其实它是可以通过第一种模型来模拟的,每需要压入一个新的元素的时候,就先开辟一个空间,数据存入这个空间,然后再修改栈顶元素指针使其指向这个新的栈顶元素。 
 
       换句话说,用链表的话,只要有足够的空间可开辟出来作为一个节点,那么两种堆栈模型都能实现(当然“无底洞”型还是如上面说的那样是用第一种模拟出来的,否则平移的工作量相当可观),如果用数组,由于数组在内存中是连续分配出来的空间,用第一种模型更自然一些。

猜你喜欢

转载自blog.csdn.net/qq_36171263/article/details/92119518