栈的两种C++实现

 

 栈是应用最广泛的数据结构之一,很有必要对其进行一些总结。

栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈的顶(top),它是后进先出(LIFO)的。对栈的基本操作只有push(进栈)和pop(出栈)两种,前者相当于插入,后者相当于删除最后的元素。

栈本质上是一种受限制的表,所以可以使用任何一种表的形式来实现它,最常用的是使用链表和数组。

使用链表的特点:不需要指定其大小,不会浪费空间;进栈和出栈涉及到动态内存的申请释放,时间花销大;

使用数组的特点:需要指定其大小,有可能浪费空间,也可能空间不够用;进栈和出栈不涉及动态内存的申请释放,因此时间上几乎没有花销;另外支持随机存取。

 

结论:一般使用链表是首选,除非满足两个条件:1.对运行时的效率要求极高;2.能够预知栈需要的空间大小。

 

 下面是利用单链表实现的栈:

/*stack.h  (slist.h is the heaher file of single list class SList)*/  
#include "slist.h"   
  
template<typename T>  
class Stack  
{  
public: //不需要自行定义copying函数,编译器自动的合成的版本工作正常:调用基类和各个数据成员的相应的copying函数。 
    Stack();  
    Stack(const T& initdata);  
    ~Stack();  
public:  
    int IsEmpty() const;  
    void MakeEmpty();//清空。   
    int GetCount() const;  
    //void DisposeStack();//清空。对于用链表实现的Stack,这两个清空的含义相同,对于用数组实现的,两者含义不一样。   
    int Push(T data);  
    int Pop(T *data = NULL);  
    int Top(T *data) const;  
  
private:  
     SList<T> slist;  
};  
  
  
template<typename T>  
inline Stack<T>::Stack():slist()  
{  
}  
  
template<typename T>  
inline Stack<T>::Stack(const T& initdata):slist(initdata)  
{  
}  
  
template<typename T>  
inline Stack<T>::~Stack()  
{  
}  
  
template<typename T>  
inline int Stack<T>::IsEmpty() const  
{  
    return slist.IsEmpty();  
}  
  
template<typename T>  
inline void Stack<T>::MakeEmpty()  
{  
    slist.RemoveAll();  
}  
  
template<typename T>  
inline int Stack<T>::GetCount() const  
{  
    return slist.GetCount();  
}  
/*template<typename T> 
inline void Stack<T>::DisposeStack() 
{ 
    slist.RemoveAll(); 
}*/  
  
template<typename T>  
inline int Stack<T>::Push(T data)  
{  
    return slist.AddHead(data);  
}  
  
template<typename T>  
inline int Stack<T>::Pop(T *data)  
{  
    if (IsEmpty())  
        return 0;  
  
    if (data)  
        Top(data);  
  
    slist.RemoveHead();  
    return 1;  
}  
  
template<typename T>  
inline int Stack<T>::Top(T *data) const  
{  
    ASSERT(data);  
  
    if (IsEmpty())  
        return 0;  
  
    *data = slist.GetHead();  
    return 1;  
}  


 

下面是利用数组实现的栈: 

 

/*stackarray.h*/

#ifndef __STACKARRAY_H__
#define __STACKARRAY_H__

#include <assert.h>

const int EmptyTOS=-1;
const int MinStackSize=5;
const int MaxStackSize=500;


template<typename T>
class StackArray
{
public:
	StackArray(int maxsize=MaxStackSize);
	StackArray(const StackArray<T>& other);
	StackArray<T>& operator=(const StackArray<T>& other);
	~StackArray();
public:
	int IsEmpty() const;
	void MakeEmpty();
	int GetCount() const;
	int IsFull();
	int Resize(int newmaxsize);//change the capacity.
	int Push(const T& data);
	int Pop(T *data = NULL);
	int Top(T *data) const;
private:
	void DisposeStack();//释放数组所占的内存,即栈被销毁.
private:
	int capacity;
	int tos;//Top of stack for now.
	T* array;
};

template<typename T>
inline StackArray<T>::StackArray(int maxsize):capacity(maxsize),tos(EmptyTOS),array(NULL)
{
	ASSERT(capacity>=MinStackSize);
	
	try
	{
		array=new T[capacity];
	}
	catch(std::bad_alloc&)
	{
	}
}

template<typename T>
inline StackArray<T>::StackArray(const StackArray<T>& other):capacity(other.capacity),tos(other.tos),array(NULL)
{
	try
	{
		array=new T[capacity];
	}
	catch(std::bad_alloc&)
	{
	}
	if(tos>=0&&tos<capacity)
	{
		for(i=0;i<=tos;i++)
		{
			array[i]=other.array[i];
		}
	}
}

template<typename T>
inline StackArray<T>& StackArray<T>::operator=(const StackArray<T>& other)
{
	if(this==&other)
	{
		return *this;
	}
	if(array!=NULL)
	{
		delete [] array;
	}

	capacity=other.capacity;
	tos=other.tos;
	if(tos>=0&&tos<capacity)
	{
		for(i=0;i<=tos;i++)
		{
			array[i]=other.array[i];
		}
	}

	return *this;
}


template<typename T>
inline StackArray<T>::~StackArray()
{

	DisposeStack();
}

template<typename T>
inline void StackArray<T>::DisposeStack()
{
	capacity=0;
	tos=EmptyTOS;
	if(array)
	{
		delete [] array;
	}
}

template<typename T>
inline int StackArray<T>::IsEmpty() const
{ 
	return EmptyTOS==tos;
}


template<typename T>
inline void StackArray<T>::MakeEmpty()
{
	tos=EmptyTOS;
}

template<typename T>
inline int StackArray<T>::GetCount() const
{
	return tos+1;
}

template<typename T>
inline int StackArray<T>::IsFull()
{
	return tos>=capacity-1;
}

template<typename T>
inline int StackArray<T>::Resize(int newmaxsize)
{
	DisposeStack();
	capacity=newmaxsize;
	tos=EmptyTOS;
	try
	{
		array=new T[newmaxsize];
	}
	catch(std::bad_alloc&)
	{
		return 0;
	}
	return 1;
}

template<typename T>
inline int StackArray<T>::Push(const T& data)
{
	if(IsFull())
	{
		return 0;
	}
	else
	{
		array[++tos]=data;
		return 1;
	}
}

template<typename T>
inline int StackArray<T>::Pop(T* data=NULL)
{
	if(IsEmpty())
	{
		return 0;
	}
	else
	{
		if(data)
		{
			*data=array[tos];
		}
		--tos;
		return 1;
	}
}


template<typename T>
inline int StackArray<T>::Top(T* data) const
{
	if(IsEmpty())
	{
		return 0;
	}
	else
	{
		*data=array[tos];
		return 1;
	}
}

#endif  // __STACKARRAY_H__

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值