堆疊棧演算法
❶ 什麼事堆棧,堆棧有哪些運算,堆棧怎樣存儲
stack,其實就是一塊內存空間,關鍵在於他的用途.
1.對於程序指令來說
執行exe時,程序都會默認分配1M堆棧空間,vs2008等開發軟體都可以進行調整實際大小.
指令變成一條條機器碼,cpu會一條條執行.
例子:
xxxxxxx
call 0x403650 <- --
yyyyy
在執行call命令時,cpu會把下一條指令地址寫入堆棧地址空間中,當然也包括其他信息.
0x403650相當於一個子程序的地址,完事後,必然有一個ret之類的指令.這時,cpu根據先前保存的地址,也就是yyyyy這條指令所對應的地址.這樣就能繼續往下執行了.
關於這一點,用ollydbg好好玩一下,馬上就清楚了.
2.一般的應用程序編寫.
我們在編寫程序時,有時採用堆棧結構,有時採用隊列結構,這跟所採用的演算法有很大關系.
最常見的遞歸演算法,按遞歸展開的話,所有的細節就跟第1點完全一樣,好處是,大都程序員根本不關心象第1點所描述的細節.只知道其調用過程和最終執行結果.具體細節可能就不關心了.
當把遞歸演算法 用非遞歸演算法寫時,很可能你就要引入堆棧結構(其實就是人為手動申請一個內存空間,比如buffer[遞歸最深層數], 這樣,就可以編寫出直觀的順序結構的代碼. cpu也不用著因調用子程序,一次次把相關信息寫入系統的堆棧中(第1點所說)..因為buffer[]的存在就是為了避免這種情況.
--------------------
stack最常用兩種操作,push和pop. 你可以用c或是c++ 標准庫提供的實現.
如果不是大工程,基本上沒必要這么做.
搞個數組 buf[], 再搞個索引變數int index,用來指示top位置. 寫入數據時,index++,取出數據時index--
3.最常用的,但易忽略的.
平常所說的,局部變數就是在堆棧中分配的.所以他出了作用域就自動釋放了.
c語言很容易理解,不容易出錯.
但c++中,編譯器有不同的策略.
比如
CTeacher t= bar();
--
CTeacher bar()
{
CTeacher xx;
為CTeacher的成員賦值
return xx.
}
你一定為這里xx對象是局部變數,出了函數作用域,對應的內存主釋放了.
CTeacher t= bar();
因為bar()是返回一個Cteacher對象,所以這里就要執行拷貝構造函數,
你會奇怪,問題是bar()返回的對象是無效的.但執行卻不會出錯.
為什麼?
首先對堆棧的理解是對.只是c++編譯器內部會改寫bar()這個函數.
變成 void bar(CTeacher& tmp)
這樣,t就作為引用參數傳入了,函數內部創建臨時對象,然後賦值給引用對象就成了.結果當然正確了.
4. 是第2點的延伸,相當重要.
一些大的應用工程,往往配合堆來對內存進行管理.
以後你接觸一些第三方程序,一定會奇怪,要動態申請內存,直接new或malloc一個對象不就行了么,為什麼要這么麻煩.
其中一個重要原因:減少碎片,提高內存使用效率.
你先申請大的空間(new/malloc),然後藉助stack的特性來管理和控制這塊空間!!!
-------------------------------
ps:理解到這幾層差不多夠用了
❷ 什麼叫堆棧
堆和棧是兩個不同的概念。
堆(heap)上分配的內存,系統不釋放,而且是動態分配的。棧(stack)上分配的內存系統會自動釋放,它是靜態分配的。運行時棧叫堆棧。棧的分配是從內存的高地址向低地址分配的,而堆則相反。由malloc或new分配的內存都是從heap上分配的內存,從heap上分配的內存必須有程序員自己釋放,用free來釋放,否則這塊內存會一直被佔用而得不到釋放,就出現了「內存泄露(Memory
Leak)」。這樣會造成系統的可分配內存的越來越少,導致系統崩潰。
堆棧是一種執行「後進先出」演算法的數據結構。
設想有一個直徑不大、一端開口一端封閉的竹筒。有若干個寫有編號的小球,小球的直徑比竹筒的直徑略小。現在把不同編號的小球放到竹筒裡面,可以發現一種規律:先放進去的小球只能後拿出來,反之,後放進去的小球能夠先拿出來。所以「先進後出」就是這種結構的特點。
堆棧就是這樣一種數據結構。它是在內存中開辟一個存儲區域,數據一個一個順序地存入(也就是「壓入——push」)這個區域之中。有一個地址指針總指向最後一個壓入堆棧的數據所在的數據單元,存放這個地址指針的寄存器就叫做堆棧指示器。開始放入數據的單元叫做「棧底」。數據一個一個地存入,這個過程叫做「壓棧」。在壓棧的過程中,每有一個數據壓入堆棧,就放在和前一個單元相連的後面一個單元中,堆棧指示器中的地址自動加1。讀取這些數據時,按照堆棧指示器中的地址讀取數據,堆棧指示器中的地址數自動減
1。這個過程叫做「彈出pop」。如此就實現了後進先出的原則。
而堆棧寄存器就是存放堆棧的寄存器。
❸ 什麼是堆棧堆棧的操作方式有哪兩種
堆棧是一種執行「後進先出」演算法的數據結構。
堆棧就是這樣一種數據結構。它是在內存中開辟一個存儲區域,數據一個一個順序地存入(也就是「壓入——push」)這個區域之中。有一個地址指針總指向最後一個壓入堆棧的數據所在的數據單元,存放這個地址指針的寄存器就叫做堆棧指示器。開始放入數據的單元叫做「棧底」。數據一個一個地存入,這個過程叫做「壓棧」。在壓棧的過程中,每有一個數據壓入堆棧,就放在和前一個單元相連的後面一個單元中,堆棧指示器中的地址自動加1。讀取這些數據時,按照堆棧指示器中的地址讀取數據,堆棧指示器中的地址數自動減
1。這個過程叫做「彈出pop」。如此就實現了後進先出的原則。
最基本的操作方式
就是
入棧和出棧
❹ 堆棧類演算法是怎麼定義的
堆棧,自己定義個數組和指針,做一個堆棧,然後按照原理操作就可以了,這樣不容易出錯
❺ 以下代碼用java語句描述堆棧結構及演算法
摘要 1. Java中堆棧(stack)和堆(heap)
❻ 堆棧相關演算法的實驗驗證 [實驗目的] 驗證順序存儲的堆棧及其上的基本操作。(c++)
目錄
序
堆棧是什麼?
實現方式
靜態數組堆棧
動態數組堆棧
鏈式堆棧
總結
序
我一直在想一個問題,我怎麼能把一件事情說的明白呢?尤其是程序方面的知識點。思路清楚是非常重要的(只有思路清楚,表達清楚了,才能一目瞭然),這個清楚的思路怎麼表現出來?我努力去做這件事情。這篇主要圍繞堆棧來展開話題。
❼ 堆棧的特點是什麼
堆棧是一種執行「後進先出」演算法的數據結構
堆棧就是這樣一種數據結構。它是在內存中開辟一個存儲區域,數據一個一個順序地存入(也就是「壓入——push」)這個區域之中。有一個地址指針總指向最後一個壓入堆棧的數據所在的數據單元,存放這個地址指針的寄存器就叫做堆棧指示器。開始放入數據的單元叫做「棧底」。數據一個一個地存入,這個過程叫做「壓棧」。在壓棧的過程中,每有一個數據壓入堆棧,就放在和前一個單元相連的後面一個單元中,堆棧指示器中的地址自動加1。讀取這些數據時,按照堆棧指示器中的地址讀取數據,堆棧指示器中的地址數自動減 1。這個過程叫做「彈出pop」。如此就實現了後進先出的原則。
❽ 關於堆棧的計算!
1.棧頂地址是0052h,註:SP始終指向堆棧的棧頂
2.棧底為堆棧的深度,看他最後一個字的偏移地址,所以是0100h
3.ss是堆棧段的段地址,冒號前的地址就是段地址,所以是1250h
4. 壓棧後,SP的值是減少的,現在壓的是個字,所以SP減2為0050h
❾ 堆棧到底是個怎麼回事
堆棧是一種執行「後進先出」演算法的數據結構。
設想有一個直徑不大、一端開口一端封閉的竹筒。有若干個寫有編號的小球,小球的直徑比竹筒的直徑略小。現在把不同編號的小球放到竹筒裡面,可以發現一種規律:先放進去的小球只能後拿出來,反之,後放進去的小球能夠先拿出來。所以「先進後出」就是這種結構的特點。
堆棧就是這樣一種數據結構。它是在內存中開辟一個存儲區域,數據一個一個順序地存入(也就是「壓入——push」)這個區域之中。有一個地址指針總指向最後一個壓入堆棧的數據所在的數據單元,存放這個地址指針的寄存器就叫做堆棧指示器。開始放入數據的單元叫做「棧底」。數據一個一個地存入,這個過程叫做「壓棧」。在壓棧的過程中,每有一個數據壓入堆棧,就放在和前一個單元相連的後面一個單元中,堆棧指示器中的地址自動加1。讀取這些數據時,按照堆棧指示器中的地址讀取數據,堆棧指示器中的地址數自動減 1。這個過程叫做「彈出pop」。如此就實現了後進先出的原則。
堆棧是計算機中最常用的一種數據結構,比如函數的調用在計算機中是用堆棧實現的。
堆棧可以用數組存儲,也可以用以後會介紹的鏈表存儲。
下面是一個堆棧的結構體定義,包括一個棧頂指針,一個數據項數組。棧頂指針最開始指向-1,然後存入數據時,棧頂指針加1,取出數據後,棧頂指針減1。
#define MAX_SIZE 100
typedef int DATA_TYPE;
struct stack
{
DATA_TYPE data[MAX_SIZE];
int top;
};
❿ 堆和棧的區別是啥
1、堆棧空間分配
棧(操作系統):由操作系統自動分配釋放 ,存放函數的參數值,局部變數的值等。其操作方式類似於數據結構中的棧。
堆(操作系統): 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似於鏈表。
2、堆棧緩存方式
棧使用的是一級緩存, 他們通常都是被調用時處於存儲空間中,調用完畢立即釋放。
堆則是存放在二級緩存中,生命周期由虛擬機的垃圾回收演算法來決定(並不是一旦成為孤兒對象就能被回收)。所以調用這些對象的速度要相對來得低一些。
3、效率比較
棧由系統自動分配,速度較快。但程序員是無法控制的。
堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便。
4、存儲內容
棧: 在函數調用時,在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變數。注意靜態變數是不入棧的。
當本次函數調用結束後,局部變數先出棧,然後是參數,最後棧頂指針指向函數的返回地址,也就是主函數中的下一條指令的地址,程序由該點繼續運行。
堆:一般是在堆的頭部用一個位元組存放堆的大小。堆中的具體內容由程序員安排。
(10)堆疊棧演算法擴展閱讀:
簡介
單片機應用中,堆棧是個特殊存儲區,堆棧屬於RAM空間的一部分,堆棧用於函數調用、中斷切換時保存和恢復現場數據。
堆棧中的物體具有一個特性:第一個放入堆棧中的物體總是被最後拿出來, 這個特性通常稱為先進後出 (FILO—First-In/Last-Out)。 堆棧中定義了一些操作, 兩個最重要的是PUSH和POP。 PUSH(入棧)操作:堆棧指針(SP)加1,然後在堆棧的頂部加入一 個元素。
POP(出棧)操作相反,出棧則先將SP所指示的內部ram單元中內容送入直接地址定址的單元中(目的位置),然後再將堆棧指針(SP)減1.。這兩種操作實現了數據項的插入和刪除。