基于链式表的栈的类模板的C++实现

/*
  基于链表实现的栈的类模板
  该栈有以下功能:
									1.linklist建立空栈
									2.~linklist销毁栈
									3.Createstack输入n个元素来创建栈
									4.top输出并返回栈顶元素
									5.push在栈顶压入一个指定元素
									6.pop栈顶出栈
									7.stacklen输出并返回栈中元素的个数
									8.empty检测栈是否为空
									9.clear清空栈
   该栈有私有成员:
									1.tp栈顶指针,指向栈顶元素的在上一个位置
									2.bp栈底指针,指向栈中最底部的元素
									3.len栈的长度
   2017/10/16   21:21
   author:chczy
*/
#include<iostream>
#include<algorithm>
#include<new>
using namespace std;
template<class T>
struct node
{
	node<T>* nx;
	node<T>* pr;
	T data;
};

template<class T>
class linkstack {
public:
	linkstack();//建立空栈
	~linkstack() { cout << "destroy the stack!" << endl; }
	linkstack& operator = (const linkstack&);
	bool Createstack(int n);
	int top();
	void push(T e);
	void pop();
	int stacklen();
	bool empty();
	void clear();
private:
	node<T> *tp;//top pointer
	node<T> *bp;//base pointer
	int len;
};

template<class T>
linkstack<T>::linkstack()//创建空栈
{
	tp = NULL;
	bp = NULL;
	len = 0;
}

template<class T>
bool linkstack<T>::Createstack(int n)//输入元素创建一个长度为n的栈
{
	if (empty())
	{
		node<T>* L = new node<T>;
		L->nx = NULL;
		L->pr = NULL;
		int i = n;
		while (n--)
		{
			node<T>* p = new node<T>;
			cin >> p->data;
			p->nx = L->nx;//后继指向元第一节点
			L->nx = p;//头结点的后继指向现在节点
			p->pr = L;//前驱指向头结点
			if (i != n + 1)//添加了两个以上的元素
				(p->nx)->pr = p;//前第一节点的前驱指向现在节点
			if (i == n + 1)//如果这是栈中第一个元素
			{
				bp = p;
			}
		}
		tp = L;
		len = i;
		return 1;//创建成功返回1
	}
	else
	return 0;//否则返回0
}

template<class T>
linkstack<T>& linkstack<T>::operator = (const linkstack<T>& rhs)//重载赋值运算符,为析构做准备
{
	tp = rhs.tp;
	bp = rhs.bp;
	len = rhs.len;
	return *this;
}

template<class T>
int linkstack<T>::top()//打印并返回栈顶元素
{
	if (tp == bp)//如果栈顶指针等于栈底指针,即栈空,则抛出异常
		throw"null stack!\n";
	node<T>* p = tp->nx;//否则让p指向栈中第一个元素
	cout << p->data << endl;//输出栈中第一个元素的值
	return p->data;//并返回
}

template<class T>
void linkstack<T>::push(T e)//e元素入栈		
{
	node<T>* p = new node<T>;//创立新节点
	p->data = e;//赋值
	p->nx = tp->nx;//将新节点的后继更新为栈顶指针的后继,也就是让新节点的后继为原栈顶第一个元素
	tp->nx = p;//将栈顶指针的后继更新为新节点
	p->pr = tp;//新节点的前驱为栈顶指针
	if (len >= 1)//如果栈中原本就有元素
	{
		(p->nx)->pr = p;//那么就将以前的第一个元素的前驱更新为新节点
	}
	else
		bp = p;//如果是向空栈压入元素,则让栈底指针指向这个元素e所在位置
	++len;//更新长度
}

template<class T>
void linkstack<T>::pop()//栈顶元素出栈				
{
	node<T> *p = tp->nx;//取栈顶元素
	node<T> *s = p->nx;//取栈顶元素下面的一个元素
	tp->nx = s;//将栈顶指针的后继更新为栈中从上往下数的第二个元素
	if (len > 1)//如果栈中有两个及以上的元素
		s->pr = tp;//那就将栈顶元素下面的那一元素的前驱更新为tp(栈顶指针)
	else
	{
		bp = tp;//否则让栈底指针等于栈顶指针
	}
	delete p;//删除栈顶元素
	--len;//更新长度
}

template<class T>
void linkstack<T>::clear()//清空栈
{
	while (!empty()) pop();
}

template<class T>
int linkstack<T>::stacklen()//打印并返回栈的长度
{
	cout << "栈中元素的个数为:" << endl;
	cout << len << endl;
	return len;
}

template<class T>
bool linkstack<T>::empty()//检测栈是否为空,为空返回1,否则返回0
{
	if (len == 0)
		return 1;
	else
		return 0;
}

猜你喜欢

转载自blog.csdn.net/chczy1/article/details/78255135