完整的範例: heapsort
-
Container 簡介 請參考
heap1.cc 範例程式並複習四個與 memory allocation
有關的特殊成員函數.
- 像 vector, list, double ended queue, ...
等等這類資料結構稱為 containers (容器?), 專門用來把很多
homogeneous (同質的) 小資料結構 (稱之為 element 元素)
收集在一起. 不同的 containers
用途在於提供給使用者不同的存取元素方法,
或針對不同的運算提升效率.
-
heap 資料結構: 有興趣的讀者請詳閱資料結構書籍;
沒有興趣的讀者可以忽略成員函數實作 (演算法) 部分.
- heap 是一種 container, 方便使用者隨時加入新的元素,
及取出最小的元素. 適合用於處理 "排隊" 的場合,
但是其中參與排隊的元素未必是先到先贏, 而是根據它的 "優先順序"
(priority) 來決定.
- 儲存規則: 把陣列當做 complete binary tree 來存放元素, 最小
(優先順序最高) 的元素放在第 1 格 (樹根),
左右兩棵子樹的元素都比樹根大, 但彼此之間沒有關係. 以下類推. 第
0 格不使用.
- 新增: 把新元素放在最後, 再往上浮; 刪除: 把樹根拔走,
最後一個元素移到樹根, 再往下沉.
- 可用來排序. 所產生的排序法叫做 heap sort, 排序時間保証在
O(n log(n)) 之內.
-
Iterator 簡介 請參考
heap2.cc
- 動機: 像 vector, linked list, tree, ... 等等 containers,
使用者如何寫程式 "對裡面的每個 ... 的元素做 ... 動作" ?
必須要有一個機制可以讓使用者把 container
裡面的所有元素逐一取出來看, 可是又不應該讓使用者操心 container
實作的資料結構細節 (例如 tree 有 letf pointer, right pointer,
甚至 next pointer, parent pointer ...) 對於陣列而言是很簡單;
但是其他 containers 呢?
-
常用的 iterator 函數:
- CONTAINER::iterator CONTAINER::begin() const;
指到某個 container 的 "第一個" 元素的 "指標"
- CONTAINER::iterator CONTAINER::end() const;
指到某個 container 的 "比最後一個還要更後面" 元素的
"指標"
- CONTAINER::iterator
CONTAINER::iterator::operator++();
讓指到某個 container 的某個元素的 "指標"
指到下一個元素
- VALUE & CONTAINER::iterator::operator *();
取得某個 "指標" 所指到的元素 (用以當做 l-value 或
r-value)
-
Access Control 簡介 (參考 complex.cc)
public:
區段為公開的界面,
裡面的成員可以供任何人使用; private:
區段為不公開的實作細節, 只有 implementor 知道, 也就是說,
只有該類別本身的成員函數的作者可以使用 private:
區段的成員.
- 注意: access control 的目的不在保密或防止惡意寫入 (不夠的!)
而在防止程式設計師的無心之失.
- 在一個類別 C 當中, 把一個不屬於 C 的函數 f 宣告成
friend
, 可以讓 f 打破 access control, 使用到 C 的
private 區段部分的資料成員與成員函數.
- 在一個類別 C 當中, 把另外一個類別 F 宣告成
friend
, 可以讓 F 的所有成員函數打破
access control, 使用到 C 的 private
區段部分的資料成員與成員函數.
- 朋友關係未必滿足對稱律 (即使 F 是 C 的朋友, C 也未必是 F
的朋友), 也未必滿足遞移律 (即使 A 是 B 的朋友, B 是 C 的朋友, A
也未必是 C 的朋友). 到底是誰對誰開誠布公?
"我對朋友開誠布公".
- 類別中的類別 (nested class): 例如 "臺灣的國民黨", "xx
國的國民黨"... 連同外面的 scope 一起講才算是完整的類別名稱. 作業:
把
heap1.cc 所有的成員函數定義成 out-of-line functions.
- 作業: 試寫出 vector, list 與 dequeue (double-ended queue)
等三個 container 類別, 元素型別一律使用 double 就好. 要把
constructor, destructor, copy constructor, assignment operator
等實作出來. 要提供 iterator.