数据结构(c++)(1)-- 栈

      最近在复习数据结构(我用的是数据结构与算法分析c++描述 第三版的书,很不错的书,有兴趣的可以去看看)的相关知识,顺便就做了些整理,以供参考。

      栈(stack)是限制插入和删除操作只能在一个位置进行的表,该位置是表的末端,称为栈的顶。对栈的操作是push(入栈)和pop(出栈),前者相当于插入,后者则是删除最后插入的元素。最后插入的元素可以通过使用top方法在执行pop之前进行访问。对空栈的pop或top操作,在栈ADT中一般认为是一个错误。另一方面,当运行push时超出栈空间的最大内存时候,这是栈在实现过程中所受的限制,并不是ADT错误。

      下面打个比方,以便于更好理解栈。其实对于栈,是一种后进先出的表,我们可以想象这样一种现实中的场景,当汽车依次进入了一个狭窄的巷子的时候,突然发现前面有个障碍物挡住了道路,那么这个时候该怎么办?显而易见,这个时候先进去的车辆是无法挪动的,只有在最后的车辆可以通过倒车而进行行驶,当最后一辆车出去后,相应的倒数第二辆车才可以出去,一直到最后第一辆车才有可能出了这个巷子,这也正是我们的栈的工作原理。

      例如,将元素6、3、7、6、2依次插入到栈中的话,则栈的示意图如下:


由于栈是是一个表,因此任何实现表的方法都可以用来实现栈。其实栈就是对我们比较熟悉的表的操作进行了限制,对数组来说,我们可以通过下标来访问数组中的任意一个元素,而如果我们想数组表现出栈的特性,那么很容易做到的,只需要对数组进行包装,封装成一个类,该类只有显著的push和pop操作,也就是对数组的下标操作做一些限制,每次只能对数组中的最后位置进行操作(这里的最后位置指的是存放有元素的最大下标的位置)。在实际中,很明显list和vector支持栈操作,99%的情况下,它们都是合理的选择。当然对于栈的实现的选择,需要具体情况具体分析,有时候为了特殊目的而设计的实现可以运行的更快。由于栈的所有操作都是常量时间的操作,所以,除非是在很特别的环境下,否则不太可能有明显的改进。

当前两个比较流行的栈的实现方式,一个是使用链表结构,另一个则是使用数组。

1、栈的链表实现

栈的一种实现方法是使用单向链表。我们通过在表顶端插入元素来实现push,通过删除表顶端的元素实现pop。top操作知识访问表顶端的元素并返回它的值。有时pop操作 和top操作可以合二为一。这里面为什么说要将元素放在表的顶端而不是末尾或其它位置呢?这个是因为在栈中我们只关心栈定的元素,那么这个栈顶元素的访问效率问题就必须要考虑了,所以将元素放在链表的顶端,可以通过链表的头指针直接进行访问,这个访问时间是常量,而如果放在末尾,那么则需要遍历链表找到栈顶的元素,显然浪费了访问的时间,这是不可取的。

2、栈的数组实现

另一种可选的实现避免了使用链并且可能是更流行的解决方案。由于使用vector中的back、push_back、pop_back方法,实现栈特别容易。更一般的方法是使用数组进行栈的构建,下面给出一个基本的示例:

#include<iostream>
using namespace std;

#define MAXSIZE 20
template <typename Object>
class CStack
{
public:
	CStack():m_topOfStack(-1){}
	bool empty() const;
	bool pop();
	bool top(Object &item) const;
	bool push(const Object &item);
private:
	Object m_theArray[MAXSIZE];
	int m_topOfStack;
};
template <typename Object>
bool CStack<Object>::empty() const
{
	if(m_topOfStack==-1)
		return true;
	return false;
}
template <typename Object>
bool CStack<Object>::pop() 
{
	if(m_topOfStack==-1)
		return false;
	m_topOfStack--;
	return true;
}
template <typename Object>
bool CStack<Object>::top(Object &item) const
{
	if(m_topOfStack==-1)
		return -1;
	item=m_theArray[m_topOfStack];
	return true;
}
template <typename Object>
bool CStack<Object>::push(const Object &item)
{
	if(m_topOfStack>=MAXSIZE-1)
		return false;
	m_theArray[++m_topOfStack]=item;
}
在栈中,这些操作都是以常数时间运行的,而且是以非常快的常数时间运行。在某些机器上,若在带有自增和自减寻址功能的寄存器上操作,则(整数)push和pop都可以写成一条指令。最现代的计算机将栈操作作为其指令系统的一部分,这个事实强化了这样一种思想,即在计算机科学中,栈很可能是继数组之后的最基本的数据结构。

      

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值