c++数据结构 栈

栈的特点: 

栈:仅限尾部插入或删除的线性表

表尾:栈顶

表头:栈底

特性:后进先出

顺序栈:用数组实现

结构为:

template <class T>
class stack
{
public:
    stack();//初始化
    ~stack();//析构
    void push(T x);//插入元素
    void pop();//删除元素
    T top(); //查看栈顶元素
    int size();//元素个数
    bool empty();//判空
private:
    int _size; //计算数据数量
    T *p;  //创建一个指针
};

#include<iostream>
#include<vector>
using namespace std;
const int MAX_size = 500;
template <class T>
class stack
{
public:
	stack();//初始化
	~stack();//析构
	void push(T x);//插入元素
	void pop();//删除元素
	T top(); //查看栈顶元素
	int size();//元素个数
	bool empty();//判空
private:
	int _size; //计算数据数量
	T *p;  //创建一个指针
};

 //初始化
template <class T>
stack<T>::stack() {   
	_size = 0; //个数为0
	p = new T[MAX_size];//开辟500个空间
}

//析构
template <class T>
stack<T>::~stack() {
	if (p != nullptr)//当p不为空指针时释放内存,并把p变为空指针
	{
        delete[]p;
        p = nullptr;
	}
	
}

//插入数据
template <class T>
void stack<T>::push(T x)
{
	if (_size == MAX_size)//容量不足 退出
	{
		exit(1);
	}
	p[_size]=x;//容量未满,插入数据
	_size++;
}
//查看栈顶元素
template <class T>
T stack<T>::top()
{
	if (_size == 0)//没有元素的话 返回0
	{
		 exit(1);
	}
	return p[_size-1];///返回栈顶数据
}
//删除元素
template <class T>
void stack<T>::pop()
{
	if (_size == 0)
	{
		exit(1)
	}
	_size--;//元素个数减一
}

//返回元素个数
template <class T>
int stack<T>::size()
{
	return _size;//返会元素个数
}

//判空
template <class T>
bool stack<T>::empty()
{
	if (_size == 0)
	{
		return true;
	}
	return false;
}

int main()
{
	stack<int> P;
	P.push(5);
	cout << P.top() << endl;
	system("pause");
	return 0;
}

链栈:

push的实现:

  1. 先生成一个新结点
  2. 用新结点的指针指向 top节点
  3. top指针指向新节点

 pop的实现:

  1. 先生成一个新节点指向top的内部节点
  2. 删除top节点
  3. top指向新节点

#include<iostream>
using namespace std;


template<class T>//让栈元素节点类提前知道有栈
class Stack;

//定义一个栈元素节点类
template<class T>
class StackNode
{
	friend class Stack<T>;//声明栈类为节点类的友元,以便访问其私有数据
public:
	StackNode() {};
	StackNode(T _data) :data(_data), base(nullptr) {};
	~StackNode() {};
private:
	T data;
	StackNode<T>* base;
};
//栈
template<class T>
class Stack
{
public:
	Stack();
	~Stack();
	void Push(const T p);//插入元素
	void Pop();//删除元素
	T Top();//返回栈顶元素
	bool Empty();//判空
	int Size();//元素个数
private:
	int size;
	StackNode<T>* top;
};
//初始化
template<class T>
Stack<T>::Stack()
{
	size = 0;//初始个数为0
	top = nullptr;//把头指针设为空指针
}
//析构函数
template<class T>
Stack<T>::~Stack()
{
	while (!Empty())//不为空就一直删除栈顶元素
	{
		Pop();
	}
}
//添加数据
template<class T>
void Stack<T>::Push(const T p)
{
	StackNode<T>* P = new StackNode<T>(p);
	P->base = top;//p的base指向 top
	top = P;//top指向P节点
	size++;//节点数加一
}
//删除数据
template<class T>
void Stack<T>::Pop()
{
	if (size == 0)//个数为0,结束
	{
		exit(1);
	}
	StackNode<T>* P = top->base;//新建一个指针指向top内部节点(下一个节点)
	delete top;//释放top的内存
	top = P;//top指向栈顶下一个节点
	size--;//个数减一
}
//查看数据
template<class T>
T Stack<T>::Top()
{
	if (size == 0)//为空,结束
	{
		exit(1);
	}
	return top->data;//不为空,返回数据
}
//返回个数
template<class T>
int Stack<T>::Size()
{
	return size;
}
//判空
template<class T>
bool Stack<T>::Empty()
{
	if (size == 0)
	{
		return true;
	}
	return false;
}
int main()
{
	Stack<int>m;
	m.Push(6);
	cout<<m.Top()<<endl;
	cout << m.Size() << endl;
	system("pause");
	return 0;
}

栈的应用:

前中后缀表达式:

  • 前缀表达式:(波兰式把运算符放在前面,把数据放在后面。
  • 中缀表达式:正常的表达式
  • 后缀表达式:(逆波兰式),指不包含括号,运算符放在两个运算对象的后面,所有的计算运算符出现的顺序严格按照从左到右运行(不在考虑运算符的优先规则)

 前缀表达式的运算过程:

右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算,并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。

 后缀表达式的运算过程:

左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算,并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值