数据结构与算法分析(c++版) #8 顺序栈和链式栈

本文介绍了顺序栈和链式栈的实现原理,顺序栈利用数组存储,栈顶在数组末尾,操作时间复杂度为O(1)。链式栈则是在链表头部进行插入和删除,适用于动态变化的需求。同时,文章对比了两者的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

顺序栈

       顺序栈继承了虚拟栈类,并用数组存储栈的元素。顺序栈的实现,本质上是顺序表实现的简化。顺序栈以线性表的表尾作为栈顶,即当栈中有n个元素时把位置n-1作为栈顶,这样每次push或者pop操作的时间代价仅为θ(1)。

       下面是顺序栈的实现:

template <class Elem>
class AStack : public Stack<Elem>
{
private:
	int size;	//栈的最大范围
	int top;	//栈顶元素 以及栈当前的大小
	int *listArray;	 //存放栈的元素
	enum { DefaultListSize = 50 };	//栈的默认最大范围
public:
	AStack(int sz = DefaultListSize)
	{
		size = sz;	
		top = 0;	
		listArray = new Elem[sz];
	}
	~AStack() { delete [] listArray; }
//	清空栈内元素,把top设为0即可
	void clear() { top = 0; }
//	入栈
	bool push(const Elem& elem)
	{
		if (top == size) return false;
		listArray[top++] = elem;
		return true;
	}
//	出栈
	bool pop(Elem& elem)
	{
		if (top == 0) return false;
		elem = listArray[--top];
		return true;
	}
//	获取栈顶元素的值
	bool topValue(Elem& elem) const
	{
		if (top == 0) return false;
		elem = listArray[top - 1];
		return true;
	}
//	获取栈的元素个数
	int length() const
	{
		return top;
	}
};

链式栈

       链式栈的实现是对链表实现的简化。其元素只能在表头进行插入和删除。由于空栈或只有一个元素的栈都不需要特殊情形的结点,所以它不需要表头结点。

       下面个提出了链式表的实现:

template <class Elem> class Node
{
public:
	Node* next;
	Elem element;
	Node(const Elem elemval, Node* nextptr = nullptr)
	{
		element = elemval;
		next = nextptr;
	}
};

template <class Elem> 
class LStack : public Stack<Elem>
{
private:
	Node<Elem>* top;	// 栈顶元素	
	int size;	// 栈的元素个数
public:
	LStack()
	{
		top = nullptr;
		size = 0;
	}
	~LStack() { clear(); }
//  清空栈内的元素
	void clear()
	{
		while (top != nullptr)
		{
			Node<Elem>* ntemp = top;
			top = top->next;
			delete ntemp;
		}
		size = 0;
	}
//	入栈
	bool push(const Elem& elem)
	{
		// 先创建一个新结点指向top,然后再把这个结点的地址附给top
		top = new Node<Elem>(elem, top);
		++size;
		return true;
	}
//	出栈
	bool pop(Elem& elem)
	{
		if (size == 0) return false;
		elem = top->element;
		// 定义一个指针指向要出栈的元素
		Node<Elem>* ntemp = top;
		// 栈顶指向前一个元素的位置
		top = top->next;
		delete ntemp;
		--size;
		return true;
	}
//	获取栈顶元素的值
	bool topValue(Elem& elem) const
	{
		if (size == 0) return false;
		elem = top->element;
		return true;
	}
//	获取栈的元素个数
	int length() const
	{
		return size;
	}
};

顺序栈和链式栈的比较

       实现顺序栈和链式栈的所有操作都只需要常数时间,所以从时间效率上看,谁也不占名校的优势。另一个比较的基准是所需要的全部空间。
       初始时顺序栈必须说明一个固定的长度,当栈不够满时,一些空间将浪费掉。链式栈的长度可变,但是对于每个元素都需要一个链接域,从而产生了结构性开销。
       当需要实现多个栈时,可充分利用顺序表单向延伸的特性。因此,可以使用一个数组来存储两个栈,每个栈从各自的端点向中间延伸,如下图,这样浪费的空间会减少。但是,只有两个栈的空间需求有相反的关系时这种方法才奏效。也就是说,最好是一个栈增长时另一个栈缩短。当需要从一个栈中取出元素放入另一个栈时,这种方法非常有效。反之,如果两个栈同时增长,则数组中间的可用空间很快就会用完。
                


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值