contributed by < kurtislin
>
作業書寫規範:
[TOC]
: 筆記左上方已有 Table of Contents (TOC) 功能,不需要畫蛇添足c=
或 cpp=
變更為 c
或 cpp
。行號只在後續討論明確需要行號時,才要出現,否則維持精簡的展現。可留意「你所不知道的 C 語言: linked list 和非連續記憶體」裡頭程式碼展現的方式diff
標示),可附上對應 GitHub commit 的超連結,列出程式碼是為了「檢討」和「便於他人參與討論」:::info
, :::success
, :::warning
等標示,儘量用清晰的文字書寫。:::danger
則僅限授課教師作為批注使用〈
和 〉
,非「小於」和「大於」符號$gcc --version
gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
$lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 46 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 24
On-line CPU(s) list: 0-23
Vendor ID: GenuineIntel
Model name: 13th Gen Intel(R) Core(TM) i7-13700
CPU family: 6
Model: 183
Thread(s) per core: 2
Core(s) per socket: 16
Socket(s): 1
Stepping: 1
CPU(s) scaling MHz: 55%
CPU max MHz: 5200.0000
CPU min MHz: 800.0000
BogoMIPS: 4224.00
new
和 free
是密切相關的操作
q_new
建立新的鍊結串列的節點 回傳初始化完成的queue
q_free
遍歷鍊結串列 釋放所有節點 最後還要釋放head
q_insert_head
在佇列的頭部插入新元素
q_insert_tail
在佇列的尾部插入新元素
list.h
中定義的 list_add
函數將節點添加到頭部q_size
在計算佇列裡的元素數量
q_remove_head
,q_remove_tail
在移除佇列的頭部元素和尾部元素
在實作 q_remove_head
和 q_remove_tail
函數時,我們採用輸出參數模式,透過 sp 緩衝區參數和返回值同時提供元素指針與元素內容。這種設計讓單一函數調用能夠返回多種資訊,提升了函數的靈活性,使調用者可根據需求選擇獲取所需的資料形式。
q_reverse
將佇列所有元素反轉
q_swap
將相鄰的節點交換
q_delete_mid
利用快慢指標實現
q_reverseK
利用temporary list
實現,在q_reverseK
函數中,我使用了 struct list_head temp_head
而不是指標 struct list_head *temp_head
來宣告臨時頭節點,主要有以下原因:
直接宣告 struct list_head temp_head
會在函數的堆疊上分配記憶體
使用指標 struct list_head *temp_head
則需要使用 malloc
從堆中分配記憶體,並在使用完後需要 free
堆疊分配更快速,也不需要擔心記憶體洩漏
bool q_delete_dup(struct list_head *head)
{
if (!head || list_empty(head))
return false;
bool removed = false;
struct list_head *node = head->next;
while (node != head && node->next != head) {
element_t *curr_elem = list_entry(node, element_t, list);
element_t *next_elem = list_entry(node->next, element_t, list);
if (!strcmp(curr_elem->value, next_elem->value)) {
removed = true;
char *dup_val = curr_elem->value;
while (node != head) {
element_t *check_elem = list_entry(node, element_t, list);
if (!strcmp(check_elem->value, dup_val)) {
struct list_head *tmp = node->next;
list_del(node);
q_release_element(check_elem);
node = tmp;
}
else
break;
}
}
else
node = node->next;
}
return removed;
}
以上是我一開始的代碼但是不管怎麼測試都會剩下一個元素
測試資料中沒有要刪除的元素時也會有以下問題
l = [1 2 3 4]
cmd> dedup
ERROR: Calling delete duplicate on null queue
之後發現問題是出現在執行q_release_element(check_elem)
時,釋放了元素的記憶體,包括 check_elem->value
。但是dup_val
指針是指向 curr_elem->value
,所以造成懸空指標,之後改成char *dup_val = strdup(curr_elem->value);
就可以了
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.
Syncing