演算法與資料結構:圖和樹的定義 | 遍歷 | 最小生成樹 | 堆積排序 | Stack & Queue

閱讀時間約 15 分鐘
上次我們提到了演算法(algorithm),它是一種解決問題的方式。但演算法只是資料結構與演算法(Data Structures and Algorithms, DSA)這個領域的一部分。今天,我們要進一步探索這個主題,了解它的核心概念。

** 10/14新增堆積排序

什麼是資料結構與演算法呢?簡單來說,資料結構是用來組織和存儲資料的方式,而演算法則是用來處理這些資料的步驟。這兩者緊密結合,讓我們能夠有效率地解決各種計算問題。

接下來,我們會介紹一些基本概念,例如圖(graph)和樹(tree)的定義,如何進行遍歷(traversal),什麼是最小生成樹(minimum spanning tree),還有日常應用中的堆疊(stack)與佇列(queue)。


本文的資料與圖片參考以下兩個來源,後續若有程式碼會更新文章。

https://www.geeksforgeeks.org/

拉爾夫的技術隨筆-圖論

溫故知新:

編譯四階段| 直譯語言 | 陣列概念 | 除錯三妙招

為什麼要學習圖、樹,圖和樹又有什麼不同?

為什麼要學習圖和樹?

學習圖和樹這些資料結構非常重要,因為它們在真實世界中有廣泛的應用:

  1. 圖(Graph)
    • 社交網路:臉書(Facebook)或 Instagram 的使用者和他們的好友之間的連結就是一個典型的圖。節點代表使用者,邊代表好友關係。
    • 地圖與導航:像是 Google Maps 這樣的應用程式會將城市中的地點當作節點,將道路當作邊,並用權重來表示路程時間或距離,找到最短路徑。
  2. 樹(Tree)
    • 資料搜尋:像是二元搜尋樹(Binary Search Tree, BST)能夠有效地進行資料搜尋、插入與刪除操作,這是許多演算法的基礎。
    • 階層式結構:檔案系統的資料夾結構、公司內的組織圖、分類系統等,這些都是樹的應用,讓我們能夠以直觀的方式呈現資料的層次關係。

圖與樹的定義

圖(Graph) 是由以下兩個部分組成的資料結構:

  • 頂點(Vertices/Nodes):節點,代表資料點。
  • 邊(Edges/Connections):連接各節點的線,表示節點之間的關係或連結。

圖的邊可以有不同的特性:

  • 有向圖(Directed Graph):邊有方向性,連接的節點有「起點」與「終點」,通常會用箭頭表示。
  • 無向圖(Undirected Graph):邊沒有方向性,表示節點之間是相互連接的,沒有明確的起點或終點。
  • 加權圖(Weighted Graph):邊帶有數值,這個數值可以表示兩個節點之間的成本、距離或其他特徵。
  • 無加權圖(Unweighted Graph):邊不帶有任何數值。

下圖是一個有向且加權的圖,每條邊都有箭頭來表示方向,並且邊上有數字表示「權重」,例如路徑的距離或花費的成本。

圖片來源:W3Schools

圖片來源:W3Schools


樹(Tree)是圖的一種,定義比圖嚴格。

  1. 不會形成環:樹中的節點(Node)和邊(Edge)之間不會形成封閉的循環路徑。換句話說,從任何一個節點出發,不會走回自己。
  2. 有唯一的走法:在樹中,從一個節點到另一個節點只有唯一的一條路徑。
  3. 層級結構:樹通常有一個稱為「根節點(Root Node)」的頂點,其他的節點依據層級往下排列,就像檔案或公司組織圖一樣,從上到下形成層次分明的結構。

樹的實際應用如檔案系統,組織系統

下圖是樹的完整組織架構節錄,想要更進階了解的讀者可以參考:

拉爾夫的技術隨筆-圖論

raw-image
  1. 根節點(root node):樹中的最頂層節點
  2. 雙親節點(parent node):任兩層相連的節點中,較靠近「根」者,如下圖的 D 點。
  3. 子節點(child node / children):任兩層相連的節點中,較遠離「根」者,可再依其所在雙親節點的相對位置分為「左子節點(left child)」及「右子節點(right child)」。
  4. 手足節點/兄弟節點(sibling node):所有共享同一雙親節點的同層節點。
  5. 葉(leaf / leaves):沒有任何子節點的節點,
  6. 路徑(path):連接任兩節點之間所有的邊與節點。
  7. 子樹(subtree):以根以外的節點為新節點形成的小樹,可再依其所在新的根的相對位置分為「左子樹(left subtree)」及「右子樹(right subtree)」
raw-image

樹的型態:二元樹(Binary Tree

樹的種類超級多,光是二元樹就有各種不同的分支,首先介紹二元樹的長相。每個節點都有不超過 2 個的分支,以下僅介紹部分的二元樹:

raw-image

更多樹的型態介紹可以參考:拉爾夫筆記

樹的遍歷(Tree Traversal)

當我們建立好樹的結構後,接下來最重要的問題就是:如何找到我們想要的答案?在樹的世界裡,目標節點的搜尋可不是隨便找找就能找到的,這就涉及到樹的遍歷。

遍歷的意思

遍歷就是一種系統化的搜尋方式,主要有兩大類模式:

Breadth First Search (BFS) – 寬度優先搜尋

BFS 是一種優先按層級的搜尋方式,會先從樹的最上層開始,逐層搜尋每一層的所有節點,確保每個節點都被拜訪過,像是一層一層地探索整棵樹。

Depth First Search (DFS) – 深度優先搜尋

DFS 是一種優先深入某個路徑的搜尋方式,可以有三種常見遍歷方式:先序、中序、後序。它通常會沿著樹的某一路徑深入到底,然後再回頭尋找其他路徑。

以這顆樹來說,要怎麼讀過所有的節點呢?

raw-image

前序遍歷(Pre-order Traversal)

在前序遍歷中,我們的策略是先讀取根節點,然後依次深入左子樹,最後再到右子樹。具體來說,對於這棵樹,我們會先讀取左邊的節點 R、A、C、D,然後再轉到右邊的 B、E、F、G。這種遍歷方式特別適合用於需要先處理根節點的情況,像是構思或建立樹的結構。

如果你想更深入了解先序遍歷的運作方式,可以參考這裡的詳細動畫:W3Schools - Pre-order Traversal

前序遍歷

前序遍歷


中序遍歷(In-order Traversal)

在中序遍歷中,我們會從最下面的葉子節點開始,優先讀取左邊的分支。接著,依據之前的示意圖,In-order Traversal 的路徑為:C、A、D、R、E、B、G、F。這種方式讓我們可以在讀取樹的節點時,先處理左子樹,再處理根節點,最後處理右子樹。

後序遍歷(Post-order Traversal)

後序遍歷同樣是深度優先搜尋(Depth First Search, DFS)的一種方式。在這種遍歷中,我們會先讀取左子樹,然後是右子樹,最後才是根節點。後序遍歷特別適合用於刪除整棵樹,因為它確保在刪除根節點之前,已經處理了所有的子節點。

小結

  • 前序遍歷(Pre-order Traversal):根 -> 左 -> 右
  • 中序遍歷(In-order Traversal):左 -> 根 -> 右
  • 後序遍歷(Post-order Traversal):左 -> 右 -> 根

最小生成樹(Minimum Spanning Tree, MST)

介紹完搜尋結點的方式,接下來介紹一個圖論 (Graph)的重要觀念,最小生成樹。最小生成樹走完圖中所有的節點。最小生成樹需要符合以下特性:

  1. 連接所有點:每個點都要互相連接,不漏掉任何一個。
  2. 沒有環:選擇的邊不會形成迴圈(即圖中沒有某條邊讓你繞回原來的地方)。
  3. 總權重最小:你選擇的邊的權重和要是所有可能情況中的最小值,意思就是說你找到了一條連接所有點的最省錢、最短或最節省資源的路。

比喻說明

想像一下,你是市長,想要鋪設道路連接5個城市,你有幾種不同的路徑可以選擇,每條路徑的建造成本(即邊的權重)不同。為了節省預算,你需要選出能連接所有城市的最便宜的道路組合。這樣做出來的方案,就是一棵最小生成樹。實際上最小生成樹的應用可以是,電腦網絡建設、交通網路規劃、電力網。

常見的最小生成樹演算法

為了找到最小生成樹,有一些經典的演算法,他們都是貪婪演算法的延伸:

  1. Kruskal 演算法:每次選擇權重最小的邊,並避免形成環,直到所有的點都連接起來。
  2. Prim 演算法:從任一個點開始,不斷選擇連接到樹上且權重最小的邊,直到所有點都被連接。

兩者比較

  • Kruskal 演算法:可以處理不連通的圖,因為它是以邊為主,會找到最少生成樹,也可以形成最小生成森林 Minimum Spanning Forest
  • Prim 演算法:需要圖是連通的,因為它是從單一節點擴展,無法自動跳到其他不連通的節點。

Kruskal 演算法:

  1. 先計算每個點到點的距離,再從最短距離的兩個點開始。
  2. 分別是 C - E 的 2,E-D的 3 和A-B 的 4,但下一個是 5 沒有辦法連,因為會變成一個環。
raw-image
  1. 所以改走 距離為 6 的E-G,再下一步又發現是 7 不能走,所以再去找比 7 大 的邊,再把所有的邊確認完畢,刪除不可能的選項就是這張圖的最少生成樹了。
raw-image


raw-image


最短路徑分析 Dijkstra's Algorithm

  1. 將起點設為 0 其他設無限大 (Inf)。
  2. 選擇未讀過的最短距離節點。在這個例子選擇 E。
  3. 更新鄰近節點的距離:以下圖來看,走到 E 時就要把 2 填入 E。
  4. 標記節點為已讀過。
  5. 重複步驟 2 到 4,直到所有結點都讀過為止。
raw-image


raw-image
因為最短是 E,所以從 E 開始。這時 E 已經變成數字 2 了。所以 C 是 2+4=6。

因為最短是 E,所以從 E 開始。這時 E 已經變成數字 2 了。所以 C 是 2+4=6。

堆積排序(Heap Sort) : 樹的延伸排序

堆積排序是基於二元堆積(Binary Heap)資料結構的排序演算法。它的運作方式與選擇排序有點像,都是透過每次選擇最大值(或最小值),再跟未排序的數列中最左邊(或最右邊替換)。但由於他有二元樹的特性,所以時間複雜度會比選擇排序來的低。

  • Binary heap 是一個完全二元樹 (complete binary tree),完全樹的意思是除了最後一層外每一層都填滿,最後一層必須由左至右填入。

時間複雜度

堆積排序的時間複雜度為 O(nlogn),其中 O(logn) 是維持堆的結構所需的時間,而整個排序過程需要進行 n 次操作。因此,堆積排序比選擇排序更有效率,特別是在處理量資料的時候。

堆積排序的過程:

假設我的目標是,由小排到大,最頂端的數字最小。

  1. 先將待排序的陣列轉換為一個「最大堆(Max Heap)」或「最小堆(Min Heap)」。** 要最頂端的數字最小,但是一開始我要先把較大的數字換到上面。(詳見下圖)。
  2. 每次將堆頂元素(最大或最小值)取出,並將其與當前未排序部分(last element of the heap)的末端元素交換。
  3. 重新調整堆,維持最大堆或是最小堆。
  4. 重複這個過程,直到所有元素排序完成。

看起來有夠複雜,我們來看圖示:

未排序的陣列,轉成二元數。圖片來源:Geeksforgeeks。

未排序的陣列,轉成二元數。圖片來源:Geeksforgeeks。

先讀每一層,再進行交換。

先讀每一層,再進行交換。

先從父母節點和子節點開始換,父母節點要比子節點大。

先從父母節點和子節點開始換,父母節點要比子節點大。

父母節點都比子節點大了。

父母節點都比子節點大了。

最後換成,root 是最大值。

最後換成,root 是最大值。

得到每一層節點都比下一層大

把頂端最大值換到最底層:

這裡跟選擇排序有點類似,當換過之後,就不用再處理這個節點。

raw-image

上圖已經被破壞了,我們要想辦法維持它是最大堆(父母節點比子節點大)的狀態,所以要繼續進行第三步。

raw-image
raw-image

維持成最大堆後,再去最底層跟最小值換,這時候 9 和 10 已經被排序好了。

但是跟第三步一樣,已經不是最大堆或是最小堆了,所以繼續交換使其為最大堆。

raw-image

已經是最大堆了,那我們就把最頂端跟最底層的最小值交換。

raw-image

複習各種排序

演算法 | 選擇排序 | 氣泡排序 | 合併排序 | 遞迴



堆疊(Stack)佇列(Queue)

堆疊的運作方式是「後進先出」(Last In, First Out,LIFO),也就是最後放入堆疊的元素會最先被取出。想像一個裝滿書的盒子,你最後放進去的書會是最先拿出來的。

堆疊的方式如下圖,後進後出。

raw-image

當輸入 pop() 最上面的會先被拿掉

raw-image

以陣列顯示的話,輸入 pop() 會變成什麼呢?

raw-image
最後面的 3 會被踢掉,就等於是最一疊數字的最頂端會被踢掉。

最後面的 3 會被踢掉,就等於是最一疊數字的最頂端會被踢掉。

而排序的方式則是先進先出。First in First out,所以當我按 dequeue() 刪除時,會先將第一個踢出去。

raw-image



raw-image


原始的資料。

原始的資料。

刪除一個值,是從前面開始刪除。

刪除一個值,是從前面開始刪除。

DSA 相關問題補充:

旅行銷售員問題(The Traveling Salesman Problem, TSP)

給定一系列城市及任兩個城市間的距離,找出造訪每個城市一次並回到起始城市的最短路線

旅行銷售員問題是一個經典的組合最佳化問題,其目標是找到一條最短路徑,讓業務員可以在多個城市間巡迴,並最終回到起點。這個問題非常實際,尤其在物流和供應鏈管理中,但時間複雜度非常高,為 O(n!)。

為什麼是 O(n!)?

對於 n 個城市,旅行者必須考慮所有可能的城市排列。舉例來說,若有 3 個城市(例如 A、B 和 C),那麼所有的路徑排列如下:

  • A -> B -> C -> A
  • A -> C -> B -> A
  • B -> A -> C -> B
  • B -> C -> A -> B
  • C -> A -> B -> C
  • C -> B -> A -> C

這些排列的數量是 n!(n 的階乘),即 3!=3×2×1=6。若有 10 個城市,則計算量會更驚人,因為 10!=3,628,800。

樹狀圖解釋

為了更直觀地理解旅行銷售員問題,可以用樹狀圖來表示所有可能的路徑:

  1. 第一層:從城市 1(例如 A)出發。
  2. 第二層:接下來可以到城市 2(B)或城市 3(C),所以在第二層會畫出兩條分支,分別是 A -> B 和 A -> C。
  3. 第三層:如果選擇了 A -> B,則第三層會有 B -> C,然後再回到 A。如果選擇了 A -> C,則第三層會有 C -> B,然後回到 A。

這樣的樹狀圖會逐步展開,直到所有可能的排列都被列出來。最終,必須計算每條路徑的距離,並選擇最短的那一條。

詳細影片解說

4.7 Traveling Salesperson Problem - Dynamic Programming


感謝你看到這裡,有任何問題,歡迎指教~


留言0
查看全部
avatar-img
發表第一個留言支持創作者!
上回提到,演算法是一種解決問題的方法。光是簡單的將數字有小排到大就有很多種不同的排序演算法可以選擇。這次,我們來介紹幾個常見的排序演算法,看看它們是怎麼運作的。
演算法是一種解決問題的虛擬邏輯,他不像 C 語言有直接的程式碼,而是一種虛擬的問題解決方式。 想像一下,今天要在字典裡面找到 Zoo,有幾種方法: 逐頁查找:如果字典有 1000 頁,最糟情況下需要翻 1000 次 才能找到。 兩頁兩頁找:這樣的話,1000 頁最多要翻 500 次。 二分查
在上一篇文章中,我們介紹了「陣列」的基本使用方式。本篇將帶你深入探討 C 語言中字串的運作原理,了解如何以陣列形式儲存字串。此外,我們還會介紹如何將英文字母透過 ASCII 表轉換成數值,並說明其在電腦中的實際應用。最後,解析 Command Line Argument(命令列參數)的使用方法。
程式並不是寫完就可以自動運行,還需要經過「編譯」的階段。此篇文章會介紹編譯的四個階段,更貼近電腦科學。另外,也說明「陣列」的資料儲存模式跟實際的運用,提供優化程式的建議,最後再分享三個除錯的技巧。
本文深入探討程式設計中的迴圈概念,介紹三種常見的迴圈使用方式:for、while 和 do...while。透過實例如計算 1 到 100 的總和以及九九乘法表,讓讀者能夠理解這些迴圈的應用場景及其運作邏輯。文章強調掌握迴圈及函數的重要性,並提供了避免常見錯誤的提示,非常適合初學者。
為什麼從C開始? 為什麼不是python? 因為 C 是個「麻煩」的程式語言,而python 其實已經簡化很多步驟。先學C語言了解程式語言的架構,再學其他語言就會覺得更簡單! 我是搭配 CS50 的免費課程,看完影片還是不太懂,可以再搭配我的筆記複習。釐清基礎架構對電腦科學更有概念,可以更精準
上回提到,演算法是一種解決問題的方法。光是簡單的將數字有小排到大就有很多種不同的排序演算法可以選擇。這次,我們來介紹幾個常見的排序演算法,看看它們是怎麼運作的。
演算法是一種解決問題的虛擬邏輯,他不像 C 語言有直接的程式碼,而是一種虛擬的問題解決方式。 想像一下,今天要在字典裡面找到 Zoo,有幾種方法: 逐頁查找:如果字典有 1000 頁,最糟情況下需要翻 1000 次 才能找到。 兩頁兩頁找:這樣的話,1000 頁最多要翻 500 次。 二分查
在上一篇文章中,我們介紹了「陣列」的基本使用方式。本篇將帶你深入探討 C 語言中字串的運作原理,了解如何以陣列形式儲存字串。此外,我們還會介紹如何將英文字母透過 ASCII 表轉換成數值,並說明其在電腦中的實際應用。最後,解析 Command Line Argument(命令列參數)的使用方法。
程式並不是寫完就可以自動運行,還需要經過「編譯」的階段。此篇文章會介紹編譯的四個階段,更貼近電腦科學。另外,也說明「陣列」的資料儲存模式跟實際的運用,提供優化程式的建議,最後再分享三個除錯的技巧。
本文深入探討程式設計中的迴圈概念,介紹三種常見的迴圈使用方式:for、while 和 do...while。透過實例如計算 1 到 100 的總和以及九九乘法表,讓讀者能夠理解這些迴圈的應用場景及其運作邏輯。文章強調掌握迴圈及函數的重要性,並提供了避免常見錯誤的提示,非常適合初學者。
為什麼從C開始? 為什麼不是python? 因為 C 是個「麻煩」的程式語言,而python 其實已經簡化很多步驟。先學C語言了解程式語言的架構,再學其他語言就會覺得更簡單! 我是搭配 CS50 的免費課程,看完影片還是不太懂,可以再搭配我的筆記複習。釐清基礎架構對電腦科學更有概念,可以更精準
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
2.0 上古漢語的特殊結構 2.3 之乎者也 —  也 (矣﹑焉) 2.3.1 也 一﹕初探之四 現在讓我們從函數引申出來的函子/論元觀點來解析上述「也」字的用法。用初級計算機科學編程的語言來說,函子就是一個具有函數功能的物件 (object),方便我們使用﹔它的功能就是讓我們可以召喚
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 四 在以語構範疇為單位的語言結構上,同樣可以應用前述的函數概念或規則。其中一個最大的分別是,若以 1.4.2_4 為用作對比的例子,函算語法的論域 (domain of dis
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 三 弗雷格從語言結構的觀點出發,提出了函數可以被視為一個不完整的表式。如果我們將一個函數拆解為一個由一個函子及其 (一個或多個) 論元所組成的表式,那麼該函子便是一個有待滿足的
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 二 關於函數的演變和弗雷格對函數的看法,前面的 1.2 節和 1.3 節已經談論了不少。 由於函數在數學﹑邏輯學﹑計算語言學極為重要,更且是本書闡述的語法的中心概念,因此有必要再略作
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 一 上節是對語構範疇理論的簡介。 1922年,列希涅夫斯基提出了語構範疇概念,以此取代人工化的型論,並引入到他的三個形式系統中66,以圖避免羅素悖論及其它集論悖論的出現。 艾杜
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 九 為能清晰說明,我們給範疇次序標號 (即置頂的 1-5),使整個推導過程看似一個矩陣﹕ 1.4.1_5.3 艾杜凱維茨的推導矩陣 第 2 行的 gr:1 (C1, C2) 是說 gr 用於第 1 行的 C
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 七 指派範疇是第一步, 第二步是設定推導規則。 推導規則的作用是對某一給定的表式63 進行判定,看它是否一個貫通的表式(或詞構)。就上述英語例句而言,我們只需一個簡單的單向通則 (general rule)﹕6
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 五 艾杜凱維茨的語構範疇理論有兩個關於形式語言的預設﹕[Ajdukiewicz 1935: 2]57 1.4.1_1 一個詞構 (das Wortgefüge)58 必須是一個連貫的整體才具有意義。 1.
Thumbnail
1.0 從函數到函算語法 1.1 句子成份 1.2 函數概念小史 1.3 弗雷格的函數概念 七 「概念」很可能是歐洲哲學史中最常用的其中一個語詞,就好像數學工作者的「數」,但概念總是作為一種心智建構提出或使用,對弗雷格要創建的新邏輯 —— 即以客存事物為對象的新邏輯 —— 來說,它可以
Thumbnail
1.0 從函數到函算語法 1.2 函數概念小史 1.2.1 中譯的來源 數學中函數概念的重要性難以盡書,亦很難想像沒有函數概念的數學可以走多遠。誇張一點,我們可以說很大部份的數學都是按函數概念操作的。但少有人留意到,在某個意義上,函數可說是數學語言的一個語構處理。 漢語「函數」一詞乃
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
2.0 上古漢語的特殊結構 2.3 之乎者也 —  也 (矣﹑焉) 2.3.1 也 一﹕初探之四 現在讓我們從函數引申出來的函子/論元觀點來解析上述「也」字的用法。用初級計算機科學編程的語言來說,函子就是一個具有函數功能的物件 (object),方便我們使用﹔它的功能就是讓我們可以召喚
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 四 在以語構範疇為單位的語言結構上,同樣可以應用前述的函數概念或規則。其中一個最大的分別是,若以 1.4.2_4 為用作對比的例子,函算語法的論域 (domain of dis
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 三 弗雷格從語言結構的觀點出發,提出了函數可以被視為一個不完整的表式。如果我們將一個函數拆解為一個由一個函子及其 (一個或多個) 論元所組成的表式,那麼該函子便是一個有待滿足的
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 二 關於函數的演變和弗雷格對函數的看法,前面的 1.2 節和 1.3 節已經談論了不少。 由於函數在數學﹑邏輯學﹑計算語言學極為重要,更且是本書闡述的語法的中心概念,因此有必要再略作
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 一 上節是對語構範疇理論的簡介。 1922年,列希涅夫斯基提出了語構範疇概念,以此取代人工化的型論,並引入到他的三個形式系統中66,以圖避免羅素悖論及其它集論悖論的出現。 艾杜
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 九 為能清晰說明,我們給範疇次序標號 (即置頂的 1-5),使整個推導過程看似一個矩陣﹕ 1.4.1_5.3 艾杜凱維茨的推導矩陣 第 2 行的 gr:1 (C1, C2) 是說 gr 用於第 1 行的 C
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 七 指派範疇是第一步, 第二步是設定推導規則。 推導規則的作用是對某一給定的表式63 進行判定,看它是否一個貫通的表式(或詞構)。就上述英語例句而言,我們只需一個簡單的單向通則 (general rule)﹕6
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 五 艾杜凱維茨的語構範疇理論有兩個關於形式語言的預設﹕[Ajdukiewicz 1935: 2]57 1.4.1_1 一個詞構 (das Wortgefüge)58 必須是一個連貫的整體才具有意義。 1.
Thumbnail
1.0 從函數到函算語法 1.1 句子成份 1.2 函數概念小史 1.3 弗雷格的函數概念 七 「概念」很可能是歐洲哲學史中最常用的其中一個語詞,就好像數學工作者的「數」,但概念總是作為一種心智建構提出或使用,對弗雷格要創建的新邏輯 —— 即以客存事物為對象的新邏輯 —— 來說,它可以
Thumbnail
1.0 從函數到函算語法 1.2 函數概念小史 1.2.1 中譯的來源 數學中函數概念的重要性難以盡書,亦很難想像沒有函數概念的數學可以走多遠。誇張一點,我們可以說很大部份的數學都是按函數概念操作的。但少有人留意到,在某個意義上,函數可說是數學語言的一個語構處理。 漢語「函數」一詞乃