or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing
xxxxxxxxxx
2020q1 Homework1 (lab0)
contributed by <
gpwork4u
>實驗環境
作業要求
queue.[ch]
和連帶的檔案,測試後用 Git 管理各項修改,記得也該實作q_sort
函式natural sort
,在 “simulation” 也該做對應的修改,得以反映出natural sort
的使用。- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →開發過程
queue.h
根據老師提供的作業說明所作的修改,加上一個 int size 變數在每次增減元素時做紀錄。
在實作
q_insert_tail
時,要求要將原本 \(O(n)\) 的時間修改為 \(O(1)\) ,因此在queue_t
中增加一個tail
指標,以便直接在 queue 的尾端新增元素。參考 OscarShiang 同學指標的使用方法,改用
list_ele_t *tmp
指標進行操作。queue.c
q_new
q_size
把
q->size
直接傳回去就是一開始實作的時候沒考慮 queue 為 NULL 的情形,加進去之後分數會多六分
q_free
從 head 依序拜訪各個元素並作釋放
最後再將 queue 的指標釋放
q_insert_head
在 queue 為空時需要另外將 tail 也指向新增的元素
於作業說明中提到
因此在將資料傳給 newh->value 時為了避免使用 strcpy ,改採用根據 CERN 所提供的建議中的snprintf函式來進行操作。
在使用snprintf時,將參數
size_t n
設為strlen(s)
時,會發現輸出結果跟預期的不一樣,如下在經查閱C99規格書之後,其對於 snprintf的敘述如下
從中可以知道,
snprintf
會根據size_t n
,將第 n-1 個位置以後的字串捨棄,並在第 n 位放入 NULL,因此在利用 strlen(s) 作為 Buffer size 時,須加一才能將完整的 s 值傳進newh->value
。在 value 做 malloc 的時候,一開始是使用
sizeof(s)
配置記憶體空間,後來在後續的測試中發現傳入的字串大小大於等於 8 時,在進行釋放的時候會出現。後來測試的時候發現
malloc(sizeof(s))
並不會配置一個跟s
一樣的記憶體大小,而是 pointer 大小,導致在只用sizeof(s)
作分配時不夠大,在用snprintf
放入字串過大導致在釋放記憶體時動到了原本沒分配的部份,最後改用sizeof(char)*strlen(s)+1
就可解掉這個 error,在q_insert_tail
更新了一樣的作法。根據 C 規格書中對 sizeof 的描述,如傳入的 sizeof(s) 中 s 是個陣列的話,是可以直接用的,當是 pointer 時就只會是 pointer 的大小,而在 64 位元的系統中,一個 pointer 的大小即是8個 byte 。
q_insert_tail
在 queue 為空時需要另外將 head 也指向新增的元素
q_remove_head
sp
不是 NULL 且 remove 執行成功時要將被 remove 的元素值的前bufsize - 1 位放進sp
中,並且 sp 的最後一位須為 null terminator。在將被 remove 值放進 sp 中,要求要取被 remove 的元素值前 bufsize - 1 位,在 insert 時用到的
snprintf
,剛好就可以拿來使用。q_reverse
除了 queue 為 NULL 和 empty 時,
q->size
為 1 時也可以直接結束。一開始的想法是用拆一個接一個的方式從
q->head
依序將元素拆掉並重新反向接上,在接完之後需要另外將q->tail
歸位。後來想到先把
q->tail
接到q->head
上,並依序將q->head
到q->tail
之間的元素接到q->tail
後面,最後只須將q-tail
和q->head
互換位置,再將q->tail->next
接到 NULL 即可,示意圖如下。q_sort
sort.c
採用 merge sort 進行排序,即使在 worst case,merge sort 也是 \(O(nlog{n})\) 的時間複雜度。實作的部份參考 Linked List Sort
TODO:
merge
和merge_sort
這二個函式都呼叫到strcmp
,也就是 comparator,倘若想更換後者為其他函式 (或傳遞函式指標),那就需要在這兩個函式內容變更,不僅不便利,還會隱藏風險;split
函式通用性不足,可改為巨集或 inline function 實作;merge_sort
函式原型宣告的變更:- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →參考資料