首先我要說明的是stack在標準庫中是有其標頭檔案的大家不需要自己去實現乙個stack。其次實現stack可以使用動態陣列或者鍊錶兩種方式,如果大家去實現stack,我推薦大家使用動態陣列。
首先讓我們比較一下鍊錶和動態陣列的優缺點吧。
鍊錶:優點:
1,訪問最後乙個節點的時間是一樣的,0(n)
2,插入任何乙個結點的時間是一樣的
缺點:1,處理小規模的資料開銷很大,因為需要不斷的申請位址
2,即便是處理大的資料,也不見得比動態陣列快。因為記憶體讀到cache中的時候,會將hit的資料周圍都會讀進cache中。所以如果位址不是連續的,hit這個記憶體的時間其實是挺高的。
動態陣列:
優點:1,陣列在任何節點的訪問時間都是o(1),因為可以通過下標直接訪問。
2,在記憶體被hit的時候,陣列周圍的資料都被快取,所以訪問時間上也會減少
缺點:如果實現方法不好,會導致很大的重複操作,例如:
每一次push乙個資料,都申請乙個將陣列大小+1的位址。然後轉移資料,清除之前留下的資料。這是一種很不好的實現方法。
實際上,vs2010裡面自帶的stack、實現方式是通過protected中的成員變數deque來實現puck和pop的。
而deque其實是雙向佇列,
該空間中每個元素都是指標,指向另一段較大的區域,這個區域稱為緩衝區,緩衝區用來儲存deque中的資料。因此deque在隨機訪問和遍歷資料會比動態陣列慢。
所以綜上所述,如果一定要自己實現stack的話,用動態陣列更好。
但是這裡我用的是鍊錶去實現stack,也只是為了演示作用。
**中的我已經執行過了,**的注釋也很多我相信大家都能夠看的很明白。
#include "stdafx.h"
#include
#include
using namespace std;
template
class my_stack ;
//根節點要重要保護,因為這是鍊錶所有的內容都要通過根節點去查詢
my_data *root;
public:
//建構函式將root賦值為nullptr
//注意這裡是nullptr不是null,這是c++0x新的內容,希望大家在定義空指標的時候使用nullptr,這樣其實更符合規範
my_stack():root(nullptr){}
void push(type new_data)//插入資料
catch(exception &e)//std::exception用來捕捉九大異常,e.what()用來顯示異常的錯誤資訊
} }
else//如果插入時煉表不為空
catch (exception &e)
} }
} bool pop(type& new_data)//這裡使用bool返回值也是檢測返回值是否正確的乙個方法,因為pop的時候有很大的可能鍊錶內部已經為空了,這時候就要返回乙個提示。
else if(root->next==nullptr)//如果只有根節點這乙個資料
else//如果鍊錶內部有多個節點
new_data=old_ptr->data;
delete old_ptr;
new_ptr->next=nullptr;
return true; }
catch(exception &e)
} }
~my_stack()//析構函式用來**所有記憶體
} };
int main()
return 0; }
執行結果:
鍊錶堆疊C實現
typedef int elementtype typedef structlist list makeempty void insert elementtype x,int i list ptrl if i 1 i ptrl last 2 for j ptrl last j i 1 j 將a i ...
用鍊錶實現堆疊
堆疊資料一種後進先出的資料結構,只能在一端 稱為棧頂 top 對資料項進行插入和刪除。基本的堆疊操作是push和pop,push是把乙個新值壓入堆疊的頂部,pop是把堆疊的頂部的值移除並返回這個值。堆疊只提供對它的棧頂值的訪問。堆疊很容易實現,可以用靜態陣列 動態陣列 鍊錶實現堆疊。本文介紹的是鍊錶...
堆疊的鍊錶實現
鍊錶是帶頭結點的.每次執行入棧操作,都是把資料壓入第1個節點.完整 如下 include define true 1 define false 0 typedef int elementtype struct s stack typedef struct s stack stack typedef ...