iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0
Software Development

程式菜鳥自學C++資料結構演算法系列 第 9

[Day09]程式菜鳥自學C++資料結構演算法 – 堆疊Stack介紹與建立

  • 分享至 

  • xImage
  •  

前言:介紹完了陣列和鏈結串列的實作之後,接著就要進入下一個主題-堆疊。那堆疊事甚麼,又有怎麼樣的特性?
先給大家一些生活上的實例,自己發現的話印象會底較深刻喔!

範例圖:品客洋芋片
https://ithelp.ithome.com.tw/upload/images/20210923/20140187vLwghePw83.png
圖片來源:https://s.yimg.com/zp/images/0F49AD5EC9273540E2676E406BE52EC902A406B7

疊好的盤子
https://ithelp.ithome.com.tw/upload/images/20210923/20140187co6WV8JjKG.png
圖片來源:https://img95.699pic.com/xsj/00/1y/83.jpg!/fh/300

裝滿東西的袋子
https://ithelp.ithome.com.tw/upload/images/20210923/20140187kKmNEIEPoe.png
圖片來源: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回傳頂端資料等用法。
https://ithelp.ithome.com.tw/upload/images/20210923/20140187e8KfckOzpJ.png

抽象資料型別(Abstract Data Type,ADT):

在解析資料時,可能會將原本的資料轉換成不同形式處理,再以資料的樣貌顯示或存取,但在設計與分析演算法的時候,並不會針對某一個演算法特定的資料型態,而是對資料的一般特性操作方式進行討論。ADT是一種理論上的觀念,並不局限於一種特定的語言,每一種ADT更可以透過不同方式實現。
堆疊就是屬於ADT的一種,簡而言之,從抽象角度描述的數據結構之間的關係和對數據進行的操作,以堆疊為例,抽象的堆疊就是由Push、Pop等操作來定義。
之後會提到的佇列和樹也都算ADT的一種。

簡單介紹完基本的堆疊,現在要來實際創建看看, 一樣先創建一個新的專案,忘記或是初見的人如果不知道怎麼創建的話可以去Day04的陣列實作看看
≧ω≦

首先創建空堆疊並編寫基本的應用。
https://ithelp.ithome.com.tw/upload/images/20210923/20140187HgFpT2wuND.png
https://ithelp.ithome.com.tw/upload/images/20210923/20140187rek0b9Xa6g.png

可以看到最先進入堆疊的A在最後才顯示出來,表示創建成功。
https://ithelp.ithome.com.tw/upload/images/20210923/20140187dyiv7vntXJ.png

也可以將字元的資料改成字串。
https://ithelp.ithome.com.tw/upload/images/20210923/20140187OodPvuKTRJ.png
https://ithelp.ithome.com.tw/upload/images/20210923/20140187NHzePHvc2N.png

不過要注意在主程式(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();
	}

};

上一篇
[Day08]程式菜鳥自學C++資料結構演算法 – 鏈結串列實作應用之二
下一篇
[Day10]程式菜鳥自學C++資料結構演算法 – 堆 疊應用:數制轉換&括號匹配&漢諾塔
系列文
程式菜鳥自學C++資料結構演算法30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言