棧是一種重要的資料結構,是一種線性結構,具有後進先出的特點.
因為線性表有 2 種實現方式,故棧也有 2 種實現方式,即順序儲存結構和鏈式儲存結構.
本篇將以鏈式儲存結構給出一種實現方式.
和單鏈表的儲存結構類似,鏈棧的儲存映像也包括資料域和指標域兩個部分.儲存結構表示如下:
class stacknode
;
為了方便管理一組棧節點不妨定義個 stack 類如下:
class stack
;
初始化的任務就是構造乙個空棧,與鍊錶不同的是,鏈棧沒有必要設定頭節點,故只需將棧頂指標制空即可.可利用 stack 類建構函式實現,如下:
stack()
演算法步驟
建立乙個 stacknode 物件,用指標 ptr 指向.
將節點資料域制為 data.
將新節點插入棧頂.
修改棧頂指標.
具體實現如下:
bool stack::push(t data)
演算法步驟
判斷棧是否為空,若空返回false
.
將棧頂元素賦給 data.
臨時儲存棧頂元素的空間,以備釋放
修改棧頂指標,指向新的棧頂元素.
釋放原棧頂元素的指標.
具體實現如下:
bool stack::pop(t& data)
data = ptr_->data_;
stacknode* ptr = ptr_;
ptr_ = ptr_->next_;
delete ptr;
return true;
}
其中get_data
和get_next
分別為返回當前節點的資料元素和指標的函式.
當棧非空時,返回當前棧頂元素的值,具體實現如下:
t stack::get_top()
當然除了這些還可以定義其它介面,比如說,求棧長、清空棧等.這裡就不一一贅述了.
其實到這裡為止棧的資料結構基本已經實現完了,但任有改進的餘地.
比方說,如果要同時使用儲存int
型資料的棧和double
型資料的棧.上述**就顯得無能為力了. 你當然可以單獨定義乙個doublestack
類來儲存double
型資料.但為每種型別都單獨定義相同功能的類的話是不現實的(因為還有使用者自定義型別), 應用範圍有限.那有沒有一種方法可以定義一次對各種型別都適用呢? 有! c++ 的泛型.
其實在這裡我們只要稍微修改我們的**,就可以讓我們的棧儲存任意型別的資料了(這才叫容器嘛).基本思想一樣,整合如下:
#pragma once
template // 用於建立乙個棧
class stack
stacknode(t data)
stacknode(t data, stacknode* next)
// 棧節點的資料域
t data_;
// 指向下乙個棧節點的指標域
stacknode* next_;
}; // 在棧頂插入元素
bool push(t);
// 彈出棧頂元素,並儲存
bool pop(t&);
// 彈出棧頂元素
bool pop();
// 取棧頂元素
t get_top();
// 清空棧
void clear();
// 求棧長
size_t length();
// 判斷棧是否為空
bool is_empty();
stack()
private:
// 棧的頭指標,可標誌乙個棧
stacknode* ptr_;
// 棧的長度
size_t length_;
};template bool stack::push(t data)
template bool stack::pop(t& data)
data = ptr_->data_;
stacknode* ptr = ptr_;
ptr_ = ptr_->next_;
delete ptr;
--length_;
return true;
}template bool stack::pop()
stacknode* ptr = ptr_;
ptr_ = ptr_->next_;
delete ptr;
--length_;
return true;
}template inline t stack::get_top()
template void stack::clear()
length_ = 0;
}template inline size_t stack::length()
template bool stack::is_empty()
return true;
}
可寫出測試**來測試**是否正確,如下:
#include #include "linkstack.h" // 這裡存放我們編寫的棧容器
using namespace std;
int main(void)
cout << "double 棧的長度:" << double_stack.length() << endl;
cout << "int 棧的長度:" << int_stack.length() << endl;
cout << "彈出 double 棧前5個元素\n";
for (size_t i = 1; i < 5; i++)
cout << "\ndouble 棧:我的長度變了。變成:" << double_stack.length() << endl;
cout << "int 棧:我的長度沒變。還是:" << int_stack.length() << endl;
return 0;
}
執行結果如下:
接下來測試是否可以正確存放使用者自定義型別,可定義乙個平面點集如下:
注:這裡不要預設預設建構函式
class cpoint
cpoint(int x, int y)
friend std::ostream& operator<
};
測試**如下:
#include #include "linkstack.h" // 這裡存放我們編寫的棧容器
using namespace std;
int main(void)
cout << "現在棧的長度為:" << stack_point.length() << endl;
cout << "彈出所有的元素:" << endl;
while (!stack_point.is_empty())
{ cpoint point;
stack_point.pop(point);
::std::cout 結果如下:
這就很爽了,利用泛型使得我們的棧不僅可以儲存基本資料型別,還能儲存使用者自定義型別。嗯,這可能就叫一次程式設計,終身受益吧!
資料結構 實現棧
include include include define node len sizeof node 1 pstack ptop pstack pbottom都指向節點 typedef struct node pnode,node typedef struct stack pstack,stack...
資料結構 棧實現
棧和佇列不一樣,棧是後進先出。實現時用了陣列儲存棧,陣列大小根據內容自動擴充。廢話不多說,上 c mystack.h pragma once templateclass mystack templateint mystack getcount templatet mystack top templa...
資料結構 棧的實現
1 定義資料元素類 data package stack public class data override public string tostring 2 定義棧結構類 stacktype package stack public class stacktype 判斷是否空棧 return p...