一、栈的特点
栈是一种受限的线性表,它规定只能够在表的尾部进行插入和删除,我们把允许插入和删除元素的一端称为栈顶,而另一段称为栈底,没有任何元素的元素栈称为空栈。
栈中的元素进出的规则为先入后出,即先进入栈的元素后出栈而后进入栈的元素先出栈。在对栈栈中的元素进行操作时只能够操作栈顶的元素。
栈中储存元素的三种状态:
当储存的元素超过了栈的储存空间则会发生栈中元素的溢出。
向栈中插入元素叫做入栈:
top指针用于记录栈顶元素的位置
删除栈中的元素:
两个栈之间的空间共享:栈的线性储存在一开始就会指定使用多少内存空间来储存数据,但当我们向栈中储存的数据量大于栈内存时则超出部分无法储存,若此时还有另外一个栈,在这个栈中储存空间还没有用完,则很浪费,我们可以将两个栈链接实现栈之间的空间共享,链接方式为将一个栈的栈底与另一个栈的栈顶链接,此时这个栈的栈顶下标改为上一个栈的储存空间大小n-1
栈的顺序储存优点 :
只需要记录栈顶的元素的位置而不用记录元素的插入位置,而且在插入元素的时候不用再移动元素。
栈的顺序存储缺点 :
栈的顺序储存在一开始会分配固定大小内存空间来储存元素,在后面存储元素的时候内存空间不容易扩展。
二、栈与计算机
在计算机体系中栈为一个动态内存区域,程序在执行的过程中栈可以保存函数函数在调用时所需要的所有信息,这些信息包括:
1、函数的返回地址和参数
2、保存函数内部的非静态局部变量和一些编译器生成的零时变量。
三、栈的顺序储存实现
AL_StackSeq.h代码
#ifndef AL_STACKSEQ_INCLUDE
#define AL_STACKSEQ_INCLUDE
#include <windows.h>
template<typename T>
class AL_StackSeq
{
public:
static const DWORD STACKSEQ_MAXSIZE= 0xffffffff;
static const DWORD STACKSEQ_DEFAULTSIZE = 100;
AL_StackSeq(DWORD dwSize = STACKSEQ_DEFAULTSIZE);
~AL_StackSeq();
//判断栈中是否为空
bool IsEmpty()const;
//将元素弹出栈
bool Pop(T&tTypeOut);
//将元素压入栈
bool Push(T&tTemplate);
//获取栈中储存的元个数
DWORD Size()const;
//获取栈顶的元素
bool Top(T&tTypeOut)const;
//清空栈中的所有元素
void Clear();
private:
//栈中的内存分配
void GetBuffer();
//判断栈栈中内存是否储存完
bool IsFull()const;
T *m_pElements;//栈的内存
DWORD m_dwMaxSize;//栈的最大内存
DWORD m_dwSize;//记录栈中已经储存的元素个数
};
template<typename T>
inline AL_StackSeq<T>::AL_StackSeq(DWORD dwSize):m_pElements(NULL),m_dwMaxSize(dwSize),m_dwSize(0x00)
{
if (m_dwMaxSize==0x00)
{
m_dwMaxSize = 1;
}
GetBuffer();
}
template<typename T>
inline AL_StackSeq<T>::~AL_StackSeq()
{
if (m_pElements!=NULL)
{
delete[] m_pElements;
m_pElements = NULL;
}
}
template<typename T>
inline bool AL_StackSeq<T>::IsEmpty() const
{
return (m_dwSize==0x00)?true:false;
}
template<typename T>
inline bool AL_StackSeq<T>::Pop(T & tTypeOut)
{
if (IsEmpty() == true)
{
return false;
}
tTypeOut = m_pElements[Size() - 1];
m_dwSize--;
return true;
}
template<typename T>
inline bool AL_StackSeq<T>::Push(T & tTemplate)
{
if (IsFull()==true)
{
GetBuffer();
}
m_pElements[Size()] = tTemplate;
m_dwSize++;
return true;
}
template<typename T>
inline DWORD AL_StackSeq<T>::Size() const
{
return m_dwSize;
}
template<typename T>
inline bool AL_StackSeq<T>::Top(T & tTypeOut) const
{
if (IsEmpty()==true)
{
return false;
}
tTypeOut = m_pElements[Size()-1];
return false;
}
template<typename T>
inline void AL_StackSeq<T>::Clear()
{
m_dwSize = 0x00;
}
template<typename T>
inline void AL_StackSeq<T>::GetBuffer()
{
if((IsFull()==false)&&m_pElements!=NULL)
{
return;
}
if (m_pElements==NULL)
{
if (m_dwMaxSize>0)
{
m_pElements = new T[m_dwMaxSize];
}
return;
}
T *pLastType = NULL;
pLastType = m_pElements;
if (m_dwMaxSize==STACKSEQ_MAXSIZE)
{
return;
}
if (m_dwMaxSize>STACKSEQ_MAXSIZE/2)
{
m_dwMaxSize = STACKSEQ_MAXSIZE;
}
else
{
m_dwMaxSize *= 2;
}
if (m_dwMaxSize>0)
{
m_pElements = new T[m_dwMaxSize];
}
//数据的复制
for (DWORD dwCopy=0;dwCopy<Size();dwCopy++)
{
m_pElements[dwCopy] = pLastType[dwCopy];
}
delete[] pLastType;
pLastType = NULL;
}
template<typename T>
inline bool AL_StackSeq<T>::IsFull() const
{
return(Size()>=m_dwMaxSize)?true:false;
}
#endif
此时代码 :
void StackSeqTest()
{
AL_StackSeq<DWORD> cStackSeq(1);
bool bEmpty = cStackSeq.IsEmpty();
std::cout << bEmpty << std::endl;
DWORD dwPop = 0x00;
cStackSeq.Pop(dwPop);
DWORD dwTop = 0x00;
cStackSeq.Top(dwTop);
std::cout << dwTop<<" "<<dwPop<< std::endl;
for (DWORD dwCnt=1;dwCnt<16;dwCnt++)
{
DWORD s = 16-dwCnt;
cStackSeq.Push(s);
cStackSeq.Top(dwTop);
std::cout << dwTop << " ";
}
cStackSeq.Clear();
}
int main(int argc, char *argv[])
{
StackSeqTest();
getchar();
return 0;
}
运行结果: