数据结构:堆栈的区别
文章目錄
- 前言
- 數據結構角度
- 棧就像裝數據的細長桶
- 堆像一棵倒過來的樹
- 內存分配中的棧和堆
- 1.申請方式和回收方式不同
- 2.申請后系統的響應不同
- 3.申請效率的比較
- 4.申請大小的限制
- 5.堆和棧中的存儲內容
前言
使用棧就像我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,它的好處是快捷,但是自由度小。
使用堆就像是自己動手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。
數據結構角度
棧就像裝數據的細長桶
棧是一種具有后進先出性質的數據結構,也就是說后存放的先取,先存放的后取。這就如同我們要取出放在桶里面底下的東西(放入的比較早的物體),我們首先要移開壓在它上面的物體(放入的比較晚的物體)。
堆像一棵倒過來的樹
而堆就不同了,堆是一種經過排序的樹形數據結構,每個結點都有一個值。通常我們所說的堆的數據結構,是指二叉堆。堆的特點是根結點的值最小(或最大),且根結點的兩個子樹也是一個堆。由于堆的這個特性,常用來實現優先隊列,堆的存取是隨意,這就如同我們在圖書館的書架上取書,雖然書的擺放是有順序的,但是我們想取任意一本時不必像棧一樣,先取出前面所有的書,書架這種機制不同于箱子,我們可以直接取出我們想要的書。
內存分配中的棧和堆
1.申請方式和回收方式不同
堆和棧的第一個區別就是申請方式不同:棧(英文名稱是 stack)是系統自動分配空間的,例如我們定義一個 char a;系統會自動在棧上為其開辟空間。而堆(英文名稱是 heap)則是程序員根據需要自己申請的空間,例如:malloc(10) 開辟十個字節的空間。
由于棧上的空間是自動分配自動回收的,所以棧上的數據的生存周期只是在函數的運行過程中,運行后就釋放掉,不可以再訪問。而堆上的數據只要程序員不釋放空間,就一直可以訪問到,不過缺點是一旦忘記釋放會造成內存泄露。
2.申請后系統的響應不同
棧:只要棧的剩余空間大于所申請空間,系統將為程序提供內存,否則將報異常提示棧溢出。
堆:首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大于所申請空間的堆結點,然后將該結點從空閑結點鏈表中刪除,并將該結點的空間分配給程序,另外,對于大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,代碼中的 delete 語句才能正確的釋放本內存空間。另外,由于找到的堆結點的大小不一定正好等于申請的大小,系統會自動的將多余的那部分重新放入空閑鏈表中。 也就是說堆會在申請后還要做一些后續的工作這就會引出申請效率的問題。
3.申請效率的比較
根據第 1 點和第 2 點可知。
棧:由系統自動分配,速度較快。但程序員是無法控制的。
堆:是由 new 分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便。
4.申請大小的限制
棧:在 Windows 下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。如果申請的空間超過棧的剩余空間時,將提示 overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由于系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。
5.堆和棧中的存儲內容
由于棧的大小有限,所以用子函數還是有物理意義的,而不僅僅是邏輯意義。
棧: 在函數調用時,第一個進棧的是主函數中函數調用后的下一條指令(函數調用語句的下一條可執行語句)的地址,然后是函數的各個參數,然后是函數中的局部變量。注意靜態變量是不入棧的。當本次函數調用結束后,局部變量先出棧,然后是參數,最后棧頂指針指向最開始存的地址,也就是主函數中的下一條指令,程序由該點繼續運行。
堆:一般是在堆的頭部用一個字節存放堆的大小。堆中的具體內容有程序員安排。
參考文章:https://blog.csdn.net/crjmail/article/details/78870325
總結
以上是生活随笔為你收集整理的数据结构:堆栈的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于java的药品库房管理系统
- 下一篇: 用MATLAB实现人脸识别