? ? ? ??棧(stack)在計(jì)算機(jī)科學(xué)中是限定僅在表尾進(jìn)行插入或刪除操作的線性表。棧是一種數(shù)據(jù)結(jié)構(gòu),它按照后進(jìn)先出的原則存儲(chǔ)數(shù)據(jù),先進(jìn)入的數(shù)據(jù)被壓入棧底,最后的數(shù)據(jù)在棧頂,需要讀數(shù)據(jù)的時(shí)候從棧頂開始彈出數(shù)據(jù)。棧是只能在某一端插入和刪除的特殊線性表。用桶堆積物品,先堆進(jìn)來(lái)的壓在底下,隨后一件一件往堆。取走時(shí),只能從上面一件一件取。堆和取都在頂部進(jìn)行,底部一般是不動(dòng)的。棧就是一種類似桶堆積物品的數(shù)據(jù)結(jié)構(gòu),進(jìn)行刪除和插入的一端稱棧頂,另一堆稱棧底。插入一般稱為進(jìn)棧,刪除則稱為退棧。 棧也稱為后進(jìn)先出表。
? ? ? ??
基本概念
? ? ? ??首先系統(tǒng)或者數(shù)據(jù)結(jié)構(gòu)棧中數(shù)據(jù)內(nèi)容的讀取與(壓入push和 彈出pop)是兩回事!插入是增加數(shù)據(jù)彈出是刪除數(shù)據(jù) ,這些操作只能從棧頂即最低地址作為約束的接口界面入手操作 ,但讀取棧中的數(shù)據(jù) 是隨便的 沒有接口約束之說(shuō)。很多人都誤解這個(gè)理念從而對(duì)棧產(chǎn)生困惑。[1]而系統(tǒng)棧在計(jì)算機(jī)體系結(jié)構(gòu)中 又起到一個(gè)跨部件交互的媒介區(qū)域的作用 即 cpu 與內(nèi)存的交流通道 ,cpu只從系統(tǒng)給我們自己編寫的應(yīng)用程序所規(guī)定的棧入口線性地讀取執(zhí)行指令, 用一個(gè)形象的詞來(lái)形容它就是pipeline(管道線、流水線)。cpu內(nèi)部交互具體參見 EU與BIU的概念介紹。
? ? ? ??
棧
特性
? ? ? ?? 棧作為一種數(shù)據(jù)結(jié)構(gòu),是一種只能在一端進(jìn)行插入和刪除操作的特殊線性表。它按照后進(jìn)先出的原則存儲(chǔ)數(shù)據(jù),先進(jìn)入的數(shù)據(jù)被壓入棧底,最后的數(shù)據(jù)在棧頂,需要讀數(shù)據(jù)的時(shí)候從棧頂開始彈出數(shù)據(jù)(最后一個(gè)數(shù)據(jù)被第一個(gè)讀出來(lái))。棧具有記憶作用,對(duì)棧的插入與刪除操作中,不需要改變棧底指針。
? ? ? ?? 棧是允許在同一端進(jìn)行插入和刪除操作的特殊線性表。允許進(jìn)行插入和刪除操作的一端稱為棧頂(top),另一端為棧底(bottom);棧底固定,而棧頂浮動(dòng);棧中元素個(gè)數(shù)為零時(shí)稱為空棧。插入一般稱為進(jìn)棧(PUSH),刪除則稱為退棧(POP)。棧也稱為后進(jìn)先出表。
? ? ? ??
棧可以用來(lái)在函數(shù)調(diào)用的時(shí)候存儲(chǔ)斷點(diǎn),做遞歸時(shí)要用到棧!
棧與計(jì)算機(jī)
? ? ? ??
在計(jì)算機(jī)系統(tǒng)中,棧則是一個(gè)具有以上屬性的動(dòng)態(tài)內(nèi)存區(qū)域。程序可以將數(shù)據(jù)壓入棧中,也可以將數(shù)據(jù)從棧頂彈出。在i386機(jī)器中,棧頂由稱為esp的寄存器進(jìn)行定位。壓棧的操作使得棧頂?shù)牡刂窚p小,彈出的操作使得棧頂?shù)牡刂吩龃蟆?
? ? ? ??
? ? ? ??
棧在程序的運(yùn)行中有著舉足輕重的作用。最重要的是棧保存了一個(gè)函數(shù)調(diào)用時(shí)所需要的維護(hù)信息,這常常稱之為堆棧幀或者活動(dòng)記錄。堆棧幀一般包含如下幾方面的信息:
? ? ? ??
? ? ? ??
1.函數(shù)的返回地址和參數(shù)
? ? ? ??
? ? ? ??
2. 臨時(shí)變量:包括函數(shù)的非靜態(tài)局部變量以及編譯器自動(dòng)生成的其他臨時(shí)變量。
棧算法
? ? ? ?? 進(jìn)棧算法
? ? ? ??
? ? ? ??
①若TOP≥n時(shí),則給出溢出信息,作出錯(cuò)處理(進(jìn)棧前首先檢查棧是否已滿,滿則溢出;不滿則作②);
? ? ? ??
? ? ? ??
②置TOP=TOP+1(棧指針加1,指向進(jìn)棧地址);
? ? ? ??
? ? ? ??
③S(TOP)=X,結(jié)束(X為新進(jìn)棧的元素);
? ? ? ??
退棧算法
? ? ? ??
? ? ? ??
①若TOP≤0,則給出下溢信息,作出錯(cuò)處理(退棧前先檢查是否已為空棧, 空則下溢;不空則作②);
? ? ? ??
? ? ? ??
②X=S(TOP),(退棧后的元素賦給X);
? ? ? ??
? ? ? ??
③TOP=TOP-1,結(jié)束(棧指針減1,指向棧頂)。
? ? ? ??
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以后的筆記瀟汀會(huì)盡量詳細(xì)講解一些相關(guān)知識(shí)的,希望大家繼續(xù)關(guān)注、支持、頂起我的博客。
你們的關(guān)注就是我的動(dòng)力,本節(jié)筆記到這里就結(jié)束了。
瀟汀一有時(shí)間就會(huì)把自己的學(xué)習(xí)心得,覺得比較好的知識(shí)點(diǎn)寫出來(lái)和大家一起分享。
編程開發(fā)的路很長(zhǎng)很長(zhǎng),非常希望能和大家一起交流,共同學(xué)習(xí),共同進(jìn)步。
如果文章中有什么疏漏的地方,也請(qǐng)大家留言指正。也希望大家可以多留言來(lái)和我探討編程相關(guān)的問題。
最后,謝謝你們一直的支持~~~
------------------------------------------
Country: China
Tel: +86-152******41
QQ: 451292510
E-mail: xiaoting_chen2010@163.com
------------------------------------------
? ? ? ?C++完整個(gè)代碼示例(代碼在VS2005下測(cè)試可運(yùn)行)
? ? ? ?
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 */
測(cè)試代碼
?
?
#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
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
