淺談資料結構與演算法 (1) — Introduction

黃翌軒
Ian 的摳頂小學堂
May 17, 2021

這系列的文章將會試圖以一個非本科生的觀點,並用簡單易懂的方式講解一些在電腦科學領域中常見的資料結構以及相關的演算法。文章內容來自於我在臺大資工系的「資料結構與演算法」這門課中所學到的知識以及自己從不同來源所得到的內容,如對文章內容或是引用來源有疑問,歡迎在下方留言或是來信告知我~

This is the Chinese version. If you seek for the English version, please click the link below.

👉 Let’s Talk About Data Structures & Algorithms (1) — Introduction

什麼是資料結構?

既然要講解資料結構,那我們肯定要先問一個最根本的問題:「什麼是資料結構?」。我們知道現在是個資訊科技的時代,許多酷炫的應用在這十幾年來如雨後春筍般不斷冒出來,想想你一天的生活中用到多少這些應用程式。早上起床上課/班途中可能滑個 facebook 或 instagram、中午用 UberEats 或 FoodPanda 訂個外送、用 Line 傳訊息、查看 Gmail 裡面的信件等等。這些應用程式中都用到了大量各式各樣的資料,你可曾想過設計這些應用程式的人是如何整理這些資料的?

這便是資料結構派上用場的時候,資料結構顧名思義就是將資料整理成某種特定的形式,為什麼要整理成某種特定的形式呢?因為在不同的場景下我們可能會有不同的需求,比方說以下幾種情形

  • 要很快地從一堆性質相同的東西找到特定某一個 (e.g. 根據書名找到某本書)
  • 有時候可能是資料間存在某種階層式的關係 (e.g. 檔案跟資料夾)
  • 有些時候可能是要確保從某個很大堆的東西拿東西或放東西時,要按照特定的順序 (e.g. 有好幾個人在排隊,先排的先結帳)

什麼是演算法?

這幾年 AI 的熱度不斷上升,「演算法」這三個字相信大家都時常聽到,但究竟什麼是演算法?我們來看看維基百科的說明。

In mathematics and computer science, an algorithm is a finite sequence of well-defined, computer-implementable instructions, typically to solve a class of problems or to perform a computation.

簡單來說,演算法就是一連串的定義好且有序的指示,只要電腦執行這些指示,就能得到某個結果。

聽起來霧煞煞?那麼我們來講講另一個跟演算法很像的東西好了:食譜。

在食譜中我們會看到這道菜的菜名、所需要的材料有哪些、完成這道菜所需要的步驟。而演算法其實也一樣,為了要解決某些特定的問題(e.g. 做出一道菜),要給電腦哪些參數(食材),並且要告訴電腦將這些參數進行什麼樣的運算(料理步驟),最後回傳一個結果(煮好的菜)。

所以演算法就是將一個問題拆解成好幾個指令,電腦依據順序執行這些指令後,就能得出我們想要的結果。聽起來很簡單,跟食譜也沒多大差別嘛!不過當我們在討論演算法時要注意幾件事。

  1. 每個指令是電腦要看得懂的,人腦在解決問題中,其實很習慣用簡則 (heuristic),但電腦沒有那麼聰明,電腦能做的事情就是指令集裡面寫得那些而已,所以我們的指令必須要是電腦看得懂的,而要將一個問題逐步拆解成電腦看得懂的步驟還要確保邏輯正確,其實不是件簡單的事。比方說,大家應該都玩過走迷宮,你其實在走的過程中不會特別想下一步要幹嘛,反正就走,沒路再往回走就好,走一走就出去了,但電腦不一樣,若是有好多路可以走,它到底要走哪條?你總不會叫電腦「看心情」走吧?
  2. 演算法所需的參數需要定義清楚,這會跟資料結構有關。對於食譜來說,雞蛋就是雞蛋,不管是你在超市買的蛋還是去農場買的,煮出來的菜不會差太多,但對電腦來說沒有模糊的空間,每一個參數是什麼樣子都必須定義清楚。

流程圖

流程圖是一個能快速、方便地理解演算法的工具,透過圖像的呈現,我們能很快地看出演算法大概的架構,下面是一個計算平均成績是否及格的演算法的流程圖。

source: https://www.edrawsoft.com/explain-algorithm-flowchart.html

而流程圖中,不同形狀的圖案代表不同的意義,可以參考下面這個表格。

source: https://www.edrawsoft.com/explain-algorithm-flowchart.html
  • 橢圓形:演算法的開始 / 結束
  • 平行四邊形:讀入 / 顯示數據
  • 長方形:執行指令
  • 菱形:條件判斷,根據不同條件執行不同指令
  • 箭頭:指向下一個指令

虛擬碼 (Pseudocode)

上面一直提到「指令」這個詞,其實指令對電腦來說就是程式碼。人類所寫的程式碼通常都是高階的程式語言,電腦是看不懂的,電腦唯一看得懂的就是機器碼 (machine code),電腦只看得懂 0 跟 1,但人類要用 0 跟 1 來寫程式太累太麻煩了,於是人類寫完的高階程式碼會透過層層的編譯器 (compiler) 或直譯器 (interpreter) 轉換成機器碼讓電腦執行。

但即便是高階程式語言,也有好幾種,如 C, C++, C#, Java, Python, JavaScript, Swift …。不同的語言有不少的差異,如果將演算法用某種特定的語言來寫,沒有辦法轉換成其他語言,也要懂得該語言的人才能看懂,不是個很好的做法。

因此演算法也常用虛擬碼 (Pseudocode) 的方式呈現,Pseudocode 一樣是用類似程式碼的方式撰寫,但只針對 high-level 的操作進行定義,並使用一些常見的運算符號(如加減乘除、大於小於等於、AND / OR),到底要怎麼寫其實沒有一個制式化的標準,更多時候是遵循一些常規。

下圖是一個範例的 Pseudocode。

source: https://shantoroy.com/latex/how-to-write-algorithm-in-latex/

今天的文章簡單的講解了資料結構與演算法究竟是什麼東西,下一篇文章將會開始講解第一個資料結構 — Array 以及相關的演算法。如果覺得我的文章不錯,歡迎給我一點掌聲,我將非常感謝!

--

--