栈(stack)在计算机科学中是限定仅在表尾进行插入或删除操作的线性表。栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。栈是只能在某一端插入和删除的特殊线性表。用桶堆积物品,先堆进来的压在底下,随后一件一件往堆。取走时,只能从上面一件一件取。堆和取都在顶部进行,底部一般是不动的。栈就是一种类似桶堆积物品的数据结构,进行删除和插入的一端称栈顶,另一堆称栈底。插入一般称为进栈,删除则称为退栈。 栈也称为后进先出表。
基本概念
首先系统或者数据结构栈中数据内容的读取与(压入push和 弹出pop)是两回事!插入是增加数据弹出是删除数据 ,这些操作只能从栈顶即最低地址作为约束的接口界面入手操作 ,但读取栈中的数据 是随便的 没有接口约束之说。很多人都误解这个理念从而对栈产生困惑。[1]而系统栈在计算机体系结构中 又起到一个跨部件交互的媒介区域的作用 即 cpu 与内存的交流通道 ,cpu只从系统给我们自己编写的应用程序所规定的栈入口线性地读取执行指令, 用一个形象的词来形容它就是pipeline(管道线、流水线)。cpu内部交互具体参见 EU与BIU的概念介绍。
栈
特性
栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。
栈可以用来在函数调用的时候存储断点,做递归时要用到栈!
栈与计算机
在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈中,也可以将数据从栈顶弹出。在i386机器中,栈顶由称为esp的寄存器进行定位。压栈的操作使得栈顶的地址减小,弹出的操作使得栈顶的地址增大。
栈在程序的运行中有着举足轻重的作用。最重要的是栈保存了一个函数调用时所需要的维护信息,这常常称之为堆栈帧或者活动记录。堆栈帧一般包含如下几方面的信息:
1.函数的返回地址和参数
2. 临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。
栈算法
进栈算法
①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);
②置TOP=TOP+1(栈指针加1,指向进栈地址);
③S(TOP)=X,结束(X为新进栈的元素);
退栈算法
①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈, 空则下溢;不空则作②);
②X=S(TOP),(退栈后的元素赋给X);
③TOP=TOP-1,结束(栈指针减1,指向栈顶)。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以后的笔记潇汀会尽量详细讲解一些相关知识的,希望大家继续关注、支持、顶起我的博客。
你们的关注就是我的动力,本节笔记到这里就结束了。
潇汀一有时间就会把自己的学习心得,觉得比较好的知识点写出来和大家一起分享。
编程开发的路很长很长,非常希望能和大家一起交流,共同学习,共同进步。
如果文章中有什么疏漏的地方,也请大家留言指正。也希望大家可以多留言来和我探讨编程相关的问题。
最后,谢谢你们一直的支持~~~
------------------------------------------
Country: China
Tel: +86-152******41
QQ: 451292510
E-mail: xiaoting_chen2010@163.com
------------------------------------------
C++完整个代码示例(代码在VS2005下测试可运行)
AL_StackSeq.h
/** @(#)$Id: AL_StackSeq.h 31 2013-09-05 09:02:18Z xiaoting $ @brief Stack (stack) in computer science is limited only in the end of the table to insert or delete operations linear form. A stack is a data structure that in accordance with the principle of LIFO data storage, data is first pushed into the end of the last data in the stack, you need to read the data when the data from the topmost pop. The stack is only one end of the inserted and deleted special linear form. Buckets stacked items, first came under pressure in the heap, followed by a one to the heap. Removed, only a one taken from above. Take the top of the heap and are carried at the bottom of the general is not moving. Stack is a similar data structure barrels stacked items, delete and insert one end of said stack, said another pile bottom of the stack. Insert commonly known as the push to delete is called the stack back. Also known as LIFO stack table. @Author $Author: xiaoting $ @Date $Date: 2013-09-05 17:02:18 +0800 (周四, 05 九月 2013) $ @Revision $Revision: 31 $ @URL $URL: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_StackSeq.h $ @Header $Header: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_StackSeq.h 31 2013-09-05 09:02:18Z xiaoting $ */ #ifndef CXX_AL_STACKSEQ_H #define CXX_AL_STACKSEQ_H /////////////////////////////////////////////////////////////////////////// // AL_StackSeq /////////////////////////////////////////////////////////////////////////// template<typename T> class AL_StackSeq { public: static const DWORD STACKSEQ_MAXSIZE = 0xffffffff; static const DWORD STACKSEQ_DEFAULTSIZE = 100; /** * Construction * * @param DWORD dwSize (default value: STACKSEQ_DEFAULTSIZE) * @return * @note * @attention */ AL_StackSeq(DWORD dwSize = STACKSEQ_DEFAULTSIZE); /** * Destruction * * @param * @return * @note * @attention */ ~AL_StackSeq(); /** * Empty * * @param VOID * @return BOOL * @note Returns true stack is empty * @attention */ BOOL Empty() const; /** * Pop * * @param VOID * @return T * @note Remove the top element and return data top element * @attention if empty does not return a value... (please judge the stack is empty before use it) */ T Pop(); /** * Push * * @param const T& tTemplate * @return VOID * @note Add elements in the stack * @attention */ VOID Push(const T& tTemplate); /** * Size * * @param VOID * @return DWORD * @note Returns the number of elements in the stack * @attention */ DWORD Size() const; /** * Top * * @param VOID * @return DWORD * @note Back to the top element... * @attention if empty does not return a value... (please judge the stack is empty before use it) */ T Top() const; protected: private: /** * GetBuffer * * @param VOID * @return VOID * @note get the work buffer * @attention when the buffer is not enough, it will become to double */ VOID GetBuffer(); /** * IsFull * * @param VOID * @return BOOL * @note the list is full? * @attention */ BOOL IsFull() const; public: protected: private: T* m_pElements; DWORD m_dwMaxSize; DWORD m_dwSize; }; /** * Construction * * @param DWORD dwSize (default value: STACKSEQ_DEFAULTSIZE) * @return * @note * @attention */ template<typename T> AL_StackSeq<T>::AL_StackSeq(DWORD dwSize): m_pElements(NULL), m_dwMaxSize(dwSize), m_dwSize(0x00) { if (0x00 == m_dwMaxSize) { //for memory deal m_dwMaxSize = 1; } GetBuffer(); } /** * Destruction * * @param * @return * @note * @attention */ template<typename T> AL_StackSeq<T>::~AL_StackSeq() { if (NULL != m_pElements) { delete[] m_pElements; m_pElements = NULL; } } /** * Empty * * @param VOID * @return BOOL * @note Returns true stack is empty * @attention */ template<typename T> BOOL AL_StackSeq<T>::Empty() const { return (0x00 == m_dwSize) ? TRUE:FALSE; } /** * Pop * * @param VOID * @return T * @note Remove the top element and return data top element * @attention if empty does not return a value... (please judge the stack is empty before use it) */ template<typename T> T AL_StackSeq<T>::Pop() { T tTypeTemp; memset(&tTypeTemp, 0x00, sizeof(T)); if (TRUE == Empty()) { //Empty return tTypeTemp; } tTypeTemp = m_pElements[Size()-1]; memset(&m_pElements[Size()-1], 0x00, sizeof(T)); m_dwSize--; return tTypeTemp; } /** * Push * * @param const T& tTemplate * @return VOID * @note Add elements in the stack * @attention */ template<typename T> VOID AL_StackSeq<T>::Push(const T& tTemplate) { if (TRUE == IsFull()) { // full, need to get more work buffer GetBuffer(); } m_dwSize++; m_pElements[Size()-1] = tTemplate; } /** * Size * * @param VOID * @return DWORD * @note Returns the number of elements in the stack * @attention */ template<typename T> DWORD AL_StackSeq<T>::Size() const { return m_dwSize; } /** * Top * * @param VOID * @return DWORD * @note Back to the top element... * @attention if empty does not return a value... (please judge the stack is empty before use it) */ template<typename T> T AL_StackSeq<T>::Top() const { T tTypeTemp; memset(&tTypeTemp, 0x00, sizeof(T)); if (TRUE == Empty()) { //Empty return tTypeTemp; } return m_pElements[Size()-1]; } /** * GetBuffer * * @param VOID * @return VOID * @note get the work buffer * @attention when the buffer is not enough, it will become to double */ template<typename T> VOID AL_StackSeq<T>::GetBuffer() { if ( (Size() < m_dwMaxSize) &&(NULL != m_pElements) ) { //we do not need to get more buffer return; } if (NULL == m_pElements) { if(0 < m_dwMaxSize){ //get the new work buffer m_pElements = new T[m_dwMaxSize]; memset(m_pElements, 0x00, sizeof(T)*m_dwMaxSize); } return; } //we need to get more buffer, store the previous pointer T* pLastTpye = NULL; DWORD pLastSize = 0x00; // it will become to double pLastSize = m_dwMaxSize; pLastTpye = m_pElements; if (STACKSEQ_MAXSIZE/2 < m_dwMaxSize) { m_dwMaxSize = STACKSEQ_MAXSIZE; } else { m_dwMaxSize *= 2; } if(0 < m_dwMaxSize){ //get the new work buffer m_pElements = new T[m_dwMaxSize]; memset(m_pElements, 0x00, sizeof(T)*m_dwMaxSize); } //need to copy the last to the current memcpy(m_pElements, pLastTpye, sizeof(T)*pLastSize); //free the last work buffer delete[] pLastTpye; pLastTpye = NULL; } /** * IsFull * * @param * @return BOOL * @note the list is full? * @attention */ template<typename T> BOOL AL_StackSeq<T>::IsFull() const { return (m_dwMaxSize == Size()) ? TRUE:FALSE; } #endif // CXX_AL_STACKSEQ_H /* EOF */
测试代码
#ifdef TEST_AL_STACKSEQ AL_StackSeq<DWORD> cStackSeq(1); BOOL bEmpty = cStackSeq.Empty(); std::cout<<bEmpty<<std::endl; DWORD dwPop = cStackSeq.Pop(); std::cout<<dwPop<<std::endl; DWORD dwSize = cStackSeq.Size(); std::cout<<dwSize<<std::endl; DWORD dwTop = cStackSeq.Top(); std::cout<<dwTop<<std::endl; for (WORD wCnt=1; wCnt<16; wCnt++) { //push 15 14 13 12..... cStackSeq.Push(16 - wCnt); dwTop = cStackSeq.Top(); std::cout<<dwTop<<std::endl; } bEmpty = cStackSeq.Empty(); std::cout<<bEmpty<<std::endl; dwSize = cStackSeq.Size(); std::cout<<dwSize<<std::endl; while (0x00 != cStackSeq.Size()) { dwPop = cStackSeq.Pop(); std::cout<<dwPop<<std::endl; } #endif
[置顶] ※数据结构※→☆线性表结构(stack)☆============栈 序列表结构(stack sequence)(六)