跟着《算法导论》学习——数据结构之栈

读前声明:本人所写帖子主要为了记录本人学习的一个过程,无他想法,由于内容比较肤浅,如有雷同,非常正常!!!

本文内容:

栈是一种最常用和最重要的数据结构,它的用途非常广泛。例如,汇编处理程序中的句法识别和表达式计算就是基于栈实现的。栈还经常使用在函数调用时的参数传递和函数值的返回方面。

通常,栈可定义为只允许在表的末端进行插入和删除的线性表。允许插入和删除的一端叫做栈顶,而不允许插入和删除的另一端叫栈底。当栈没有任何元素是则称为空栈,其特性即为后进先出(Last In First Out)。

其栈的抽象数据类如下:

template <class T>
class Stack
{
public:
	Stack(){};									//构造函数
	virtual void Push(const T& x) = 0;			//新元素x进栈
	virtual bool Pop(T& x) = 0;					//栈顶元素出栈,由x返回
	virtual bool getTop(T& x)const = 0;			//读取栈顶元素,由x返回
	virtual bool IsEmpty()const = 0;			//判断栈是否空	
	virtual bool IsFull()const = 0;				//判断栈是否满
//	virtual int getSize() const = 0;			//计算栈中元素个数
};

栈的抽象数据类型有两种典型的存储表示:基于数组的存储表示和基于链表的存储表示。基于数组的存储表示实现的栈为顺序栈,基于链表的存储表示实现的栈称为链式栈。

1、顺序栈

类定义

#include <assert.h>
#include <iostream>
#include "stack.h"
using namespace std;
const int stackIncreament = 20;				//栈溢出时扩展空间的增量
template <class T>
class SeqStack: public Stack<T>
{
public:
	SeqStack(int sz=50);
	~SeqStack(){delete []elements;}
	void Push(const T& x);                  //如果栈满了,则溢出处理;若没满,就将数据插入栈顶
	bool Pop(T& x);					        //如果栈空,则不执行退栈,返回false;否则退掉位于栈顶的元素,返回true;退出的元素通过引用型参数x返回
	bool getTop(T& x)const;                      //如果栈空,返回false;否则返回true;并通过引用型参数x得到栈顶元素的值
	bool IsEmpty()const{return (top==-1)?true:false;}
	bool IsFull()const{return (top==maxSize-1)?true:false;}
	int getSize()const{return top+1;}
	void MakeEmpty(){top=-1;}
	friend ostream& operator<<<T>(ostream &os,SeqStack<T> &s);
private:
	T *elements;
	int top;
	int maxSize;
	void OverflowProcess();
};

类的成员函数定义:

template <class T>
SeqStack<T>::SeqStack(int sz):top(-1),maxSize(sz)
{
	elements = new T[maxSize];
	assert(elements!=NULL);
};

template <class T>
void SeqStack<T>::OverflowProcess()
{
	T *newArray = new T[maxSize+stackIncreament];
	if (newArray==NULL)
	{
		cout<<"存储分配失败"<<endl;
		exit(1);
	}
	for (int i=0;i<=top;i++)
	{
		newArray[i] = elements[i];
	}
	maxSize = maxSize + stackIncreament;
	delete []elements;
	elements = newArray;
};

template <class T>
void SeqStack<T>::Push(const T& x)
{
	if (IsFull()==true)
	{
		OverflowProcess();
	}
	elements[++top] = x;
};

template <class T>
bool SeqStack<T>::Pop(T& x)
{
	if (IsEmpty()==true)
	{
		return false;
	}
	x = elements[top--];
	return true;
};

template <class T>
bool SeqStack<T>::getTop(T& x)const
{
	if (IsEmpty()==true)
	{
		return false;
	}
	x = elements[top];
	return true;
};

template <class T>
ostream& operator<<(ostream &os,SeqStack<T> &s)
{
	os<<"top ="<<s.top<<endl;
	for (int i=0;i<=s.top;i++)
	{
		os<<i<<":"<<s.elements[i]<<endl;
	}
	return os;
};

2、链式栈

链式栈是线性表的链接存储方式,采用链式栈来表示一个栈,便于结点的插入与删除。链式栈的栈顶在链表的表头,因此新结点的插入和栈顶结点的删除都是在链表的表头,即栈顶进行。

首先引入链表结点模板类:

template <class T>
struct LinkNode
{
	T data;          //数据域
	LinkNode<T> *link;			//链指针域
	LinkNode(LinkNode<T> *ptr=NULL) {link = ptr;}    //构造函数
	LinkNode(const T &item,LinkNode<T> *ptr=NULL)
	{
		data = item;
		link = ptr;
	}
};
链式栈的类定义

template <class T>
class LinkedStack:public Stack<T>
{
public:
	LinkedStack():top(NULL){}
	~LinkedStack(){makeEmpty();}
	void Push(const T& x);						//进栈
	bool Pop(T& x);								//退栈
	bool getTop(T& x)const;							//读取栈顶元素
	bool IsEmpty()const{return (top==NULL)? true:false;}
	int getSize()const;							//计算元素个数
	void makeEmpty();							//清空栈内内容
	friend ostream& operator<<<T>(ostream& os,LinkedStack<T>& s);
private:
	LinkNode<T> *top;        //栈顶指针
};
链式栈的成员函数定义:

template <class T>
void LinkedStack<T>::makeEmpty()
{
	//逐次删去栈中的元素直至栈顶指针为空
	LinkNode<T> *p;
	while (top!=NULL)
	{
		p = top;
		top = top->link;
		delete p;
	}
};

template <class T>
bool LinkedStack<T>::Pop(T& x)
{
	if (IsEmpty()==true)
	{
		return false;
	}
	LinkNode<T> *p = top;
	top = top->link;
	x = p->data;
	delete p;
	return true;
};

template <class T>
void LinkedStack<T>::Push(const T& x)
{
	top = new LinkNode<T>(x,top);
	assert(top!=NULL);
};

template <class T>
bool LinkedStack<T>::getTop(T& x)const
{
	if (IsEmpty()==true)
	{
		return false;
	}
	x = top->data;
	return true;
};

template <class T>
int LinkedStack<T>::getSize()const
{
	int size=0;
	LinkNode<T> *p=top;
	while (p!=NULL)
	{
		p = p->link;
		size++;
	}
	delete p;
	return size;
};

template <class T>
ostream & operator<<(ostream& os,LinkedStack<T>& s)
{
	os<<"栈的元素个数为:"<< s.getSize()<<endl;
	LinkNode<T> *p = s.top;
	int i = 0;
	while (p!=NULL)
	{
		os<<++i<<":"<<p->data<<endl;
		p = p->link;
	}
	return os;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值