contributed by < Benny1117Yen
>
sysprog2019
注意看作業要求,對於共筆格式有諸多規範。從細節小處做起!
CMU Introduction to Computer Systems (ICS) 準備了 C Programming Lab 作為檢閱學生 C 語言程式設計的認知:
實驗目標為實作 queue
queue.h
這檔案含有以下結構宣告:
如圖所示,將它們組合在一起以實現字符串駐列。駐列的上層表示形式是 queue_t
類型的結構。在開始代碼中,此結構僅包含單一個字段 head
,之後需要變再添加其他字段。駐列內容表示為單鏈接列表,每個元素由類型為 list_ele_t
的結構表示,具有字段 value
和 next
,分別存儲指向字符串的指針和指向下一個 list元素
的指針。最終列表元素的下一個指針設置為 NULL
。您可以將其他字段添加到結構 list_ele
中,儘管不必這樣做。
value
字段,該字段指向一個字符矩陣(C的字符串表示形式),next
字段指向下一個列表元素。字符根據 ASCII
編碼(以十六進制顯示)進行編碼。回想一下,C 語言裡面字符串表示是型態為 char
的有值陣列。在大多數機器中,數據類型 char
表示為 1 byte
。為了存儲長度為 l
的字符串,該陣列包含 l + 1
個元素,前一個 l
存儲字符的代碼(通常為 ASCII1
格式),最後一個設置為 0
。列表元素的 value
字段是一個指針指到字符的陣列。該圖表示列表 [“ cab”,“ bead”,“ cab”]
的表示形式,其中字符 a–e
以十六進製表示為 ASCII
碼 61–65
。 觀察字符串 “cab”
的兩個實例是如何由分離的陣列們來表示 – 每個列表元素應具有其字符串的分離副本。
在我們的 C
代碼中,駐列是類型為 queue_t *
的指針。我們區分兩種特殊情況:NULL
駐列是指針值為 NULL
。空駐列是指向有效結構,但是頭 (head) 字段的值為 NULL
。所以代碼將需要正確處理這兩種情況,以及包含一個或多個元素的駐列。
Your task is to modify the code in queue.h
and queue.c
to fully implement the following functions.
q_new
: 創造新的空駐列。
q_free
: 釋放駐列所佔用的記憶體。
q_insert head
: 在駐列頭 (head) 加入 (insert) 新元素(以 LIFO 準則)。
q_insert tail
: 在駐列尾 (tail) 加入 (insert) 新元素(以 FIFO 準則)。
q_remove head
: 在駐列頭 (head) 去除 (remove) 元素。
q_size
: 算出駐列中的元素量。
q_reverse
: 以反向次序重新排列列表。這函數不該分配或釋放任何列表元素 (不論是直接地或呼叫其他有分配或釋放列表元素功能的函數。) 也就是說,它只能重排已經存在的元素。
在這兩個文件的註釋中可以找到更多詳細信息,包括如何處理無效的操作(例如,從空駐列或 NULL
駐列中刪除),以及函數應具有的副作用和返回值。
對於以字符串作為參數的函數,必須通過調用 malloc
分配空間(記住要包含終止字符的空間),然後從原始空間複製到新分配的空間,來創建和存儲字符串的副本。當需要釋放列表元素時,還必須釋放字符串使用的空間。不能假設字符串的長度有任何固定的上限 – 必須根據字符串的長度為每個字符串分配空間。
其中兩個功能:q_insert_tail
和 q_size
將需要您付出一些努力才能達到所需的性能標準。原生執行將需要 O(n)
個步驟來處理具有 n
個元素的駐列。我們要求您的執行在時間 O(1)
內進行操作,即無論駐列大小如何,該操作僅需要固定數量的步驟。您可以藉由在 queue_t
數據結構中包括 (include) 其他字段並在插入,刪除和反轉列表元素時正確管理這些值來執行。
您的程序將在具有 1,000,000
個以上元素的駐列上進行測試。會發現無法使用遞歸函數在如此長的列表上進行操作,因為這將需要過多的堆棧 (stack) 空間。相反,需要使用循環 (loop) 遍歷 (traverse) 列表中的元素。
文字訊息 不要 用圖片展現!
queue.h
依照內容中的註解需求,新增以下程式碼
list_ele_t *tail
指向 tail
列表元素int size
為 queue 的大小queue.c
queue_t *q_new()
這是初始化的步驟
NULL
的駐列,若不能分配空間時,回傳 NULL
。void q_free(queue_t *q)
NULL
時,指針指到 head
,指針的前一個位子為 NULL
。ptr
有值 (指到頭),那麼 prev
就等於 ptr
,ptr
去指向 next
。ptr
指標就能指到要刪除的元素,要記得釋放指針指到的值記憶體大小跟指針本身記憶體大小。直到整個駐列清空。free(q)
釋放駐列所占記憶體大小。q_insert_head
malloc
配置一個空間給它。strcpy
把值 copy 給 value
,也就是新的駐列的記憶體位址。size
為 1
時,駐列尾指向新指針。q_inset_tail
q_insert_head
概念相同,每次執行後 q->tail
要後移一個才會指向最後一個值。q_remove_head
q->head = q->head->next
並不會受到影響因為會被更新為 NULL。由於現在 list 內沒有任一結點,所以我們也要把 tail 設為 NULL。q_size
q_reverse
qtest
分數Pseudo code
。qtest
技巧 – signal handler待補
待補