前言:介紹完了陣列和鏈結串列的實作之後,接著就要進入下一個主題-堆疊。那堆疊事甚麼,又有怎麼樣的特性?
先給大家一些生活上的實例,自己發現的話印象會底較深刻喔!
範例圖:品客洋芋片
圖片來源:https://s.yimg.com/zp/images/0F49AD5EC9273540E2676E406BE52EC902A406B7
疊好的盤子
圖片來源:https://img95.699pic.com/xsj/00/1y/83.jpg!/fh/300
裝滿東西的袋子
圖片來源:https://png.pngtree.com/png-vector/20190905/ourmid/pngtree-paper-bag-with-food-cucumbers-tomatoes-png-image_1724444.jpg
有發現這些東西的相同點嗎?
是不是拿東西的時候都是從最上方開始拿的,況且這些最上方的東西都是最晚放進去的,這就是堆疊最終要的特性「後進先出(LIFO: Last in First Out)」。
堆疊其實是一群相同資料型態的組合,所有的動作均在堆疊頂端進行,此外堆疊還有許多中應用,最常被用在副程式、遞迴的呼叫和記憶體的使用。
堆疊的操作:在堆疊中增添資料稱為『推進Push』,以及刪去元素稱為『移出Pop 』,這兩個事堆疊最常用且最基本的函示,其他還有Create建立新的堆疊和Peek回傳頂端資料等用法。
在解析資料時,可能會將原本的資料轉換成不同形式處理,再以資料的樣貌顯示或存取,但在設計與分析演算法的時候,並不會針對某一個演算法特定的資料型態,而是對資料的一般特性與操作方式進行討論。ADT是一種理論上的觀念,並不局限於一種特定的語言,每一種ADT更可以透過不同方式實現。
堆疊就是屬於ADT的一種,簡而言之,從抽象角度描述的數據結構之間的關係和對數據進行的操作,以堆疊為例,抽象的堆疊就是由Push、Pop等操作來定義。
之後會提到的佇列和樹也都算ADT的一種。
簡單介紹完基本的堆疊,現在要來實際創建看看, 一樣先創建一個新的專案,忘記或是初見的人如果不知道怎麼創建的話可以去Day04的陣列實作看看
≧ω≦
首先創建空堆疊並編寫基本的應用。
可以看到最先進入堆疊的A在最後才顯示出來,表示創建成功。
也可以將字元的資料改成字串。
不過要注意在主程式(main)前要加上#include 的標頭檔才能對對字串進行較高階的操作,像是字串指定、串接等。
今日小結:了解堆疊之後,是不是覺得經常出現在生活中呢?有了熟悉感在學習上也比較不那麼排斥吧!今天簡單介紹了堆疊是甚麼以及實作創建,明天會來做括號匹配和河內塔等堆疊的延伸應用٩(●˙▿˙●)۶…⋆ฺ
template<typename T>
class SqlStack {
T* data, * top_; //建立指針變量T指向元素,及top_指向堆疊的位置
int capacity;
public:
SqlStack(int cap = 3) {
data = new T[cap];
if (!data) { top_ = 0; capacity = 0; return; } //創建失敗的情況
top_ = data; capacity = cap; //創建成功的條件
}
T& top() { //編寫top()檢查堆疊是否為空的,並返回T類型的引用變量
if (top_ == data) throw "堆疊為空";
return *(top_ - 1);
}
bool push(T e) { //編寫push()函式,且容量也會隨資料的增加變多
if (top_ - data == capacity) {
T* p = new T[2 * capacity];
if (!p) return false;
for (int i = 0; i < capacity; i++)
p[i] = data[i];
delete[] data; data = p;
top_ = data + capacity;
capacity = 2 * capacity;
}
*top_ = e; top_++; return true;
}
bool pop() { //編寫pop()函示,需先判對堆疊是否為空
if (top_ == data) return false;
top_--; return true;
}
bool empty() { //檢查堆疊是不是空的,與top()相同概念
return top_ == data;
}
void clear() { //清除堆疊所有元素
top_ == data;
}
};
#include<iostream>
#include<string>
using std::string;
int main(){
SqlStack<char> S;
S.push('A'); //push元素
S.push('B');
S.push('C');
S.push('D');
while (!S.empty()) { //pop元素直到堆疊為空
char e = S.top();
std::cout << e << " ";
S.pop();
}
SqlStack<string> S2;
S2.push("Jason");
S2.push("Allen");
S2.push("Chris");
while (!S2.empty()) { //pop元素直到堆疊為空
string e = S2.top();
std::cout << e << " ";
S2.pop();
}
};