数据结构与算法详解——栈篇(附c++实现代码)

栈的概念

  栈又叫堆栈,是一种运算受限的线性表,只能在表尾进行插入或者删除,表尾这一断也称为栈顶,另一端称为栈底,插入一般称为入栈或者压栈,删除一般称为出栈。栈的特性就是“先进先出”,例如我把1,2先后压栈,出栈的时候必须先弹出2,才能弹出1。
  注意:堆栈就是栈,而不是指堆和栈两种数据结构,还有,操作系统内存中的堆栈和数据结构中的堆栈是两回事
在这里插入图片描述

栈的实现

  栈可以用数组或者链表实现,用数组实现的称为顺序栈,用链表实现的称为链式栈,这里我实现的是顺序栈,主要的操作就是入栈和出栈,注意顺序栈还要支持动态扩容,而链表天然支持动态扩容所以链式栈不用考虑动态扩容。

template<typename DataType>
class stack {
   
public:
	virtual int size() const= 0;	//返回元素个数
	virtual bool empty() const= 0;	//栈是否为空
	virtual void push(DataType data) = 0;	//入栈
	virtual DataType pop() = 0;		//出栈
	virtual DataType top() const= 0;	//返回栈顶元素
};

template<typename DataType>
class ArrayStack : public stack<DataType> {
   		//注意这里stack也要有DataType
private:
	DataType* array=nullptr;
	int _size = 0;	//实际存储的元素个数
	int capacity = 32;	//申请的空间大小
	int _top = -1;	//栈顶
public:
	ArrayStack();
	ArrayStack(const ArrayStack& as);
	ArrayStack(DataType a[] , int n);
	ArrayStack(std::vector<DataType>& v);
	~ArrayStack();
	int size() const;
	bool empty() const;
	void push(DataType data) ;
	DataType pop();
	DataType top() const;	
	DataType operator[](int index) const;	//返回值是DataType,所以s[n]只能访问不能修改,后面const让const stack对象也能有一个访问的版本
	void printStack();
private:
	void make_space(int n);	//扩容
};

  这里定义了一个基类stack并用纯虚函数声明了一些必须实现的接口,有子类继承了stack就必须实现这几个接口。operator[]的重载可有可无,但是如果有返回值只能是DataType而不能是DataType&。

template<typename DataType>
void ArrayStack<DataType>::make_space(int n) {
   
	if (array == nullptr) 
		array = new DataType[capacity];
	
	if (capacity > n)
		return;
	while (capacity < n)
		capacity <<= 1;
	std::cout << "capacity : "<<capacity << std::endl;
	DataType *tmp = new DataType[capacity];
	for (int i = 0; i <= _top; i++)
		tmp[i] = array[i];
	delete[] array;
	array = tmp;
}

  先来看看扩容的函数,代码应该比较清晰,如果已经申请的容量capacity>要申请的容量n就直接返回,否则capacity就一直左移一位(乘2)直到大于等于n,然后重新申请capacity大小的空间,把旧空间的元素复制过去,然后释放旧空间。

template<typename DataType>
void ArrayStack<DataType>::push(DataType data) {
   
	make_space(_size + 1);
	array[++_top] = data;
	++_size;
}

template<typename DataType>
DataType ArrayStack<DataType>::pop() {
   
	if (_size == 0) 
		throw "stack is empty, no data to pop";
	DataType data = array[_top--];
	--_size;
	return data;
}

  入栈和出栈的逻辑也比较简单,需要注意入栈时需要判断是否需要扩容,出栈时需要判断栈是否为空。

完整代码

#ifndef STACK_H
#define STACK_H

#include <iostream>
#include <vector>
#include <assert.h>

template<typename DataType>
class stack {
   
public:
	virtual int size() const= 0;
	virtual bool empty() const= 0;
	virtual void push(DataType data) = 0;
	virtual DataType pop() = 0;
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值