# 2023q1 Homework1 (quiz1)
contributed by < `ItisCaleb` >
## 2023 第一週測驗題
### 測驗 `1`
list Quick Sort (Recursion ver.)
```c
static void list_sort(struct list_head *head)
{
if (list_empty(head) || list_is_singular(head))
return;
struct list_head list_less, list_greater;
INIT_LIST_HEAD(&list_less);
INIT_LIST_HEAD(&list_greater);
struct item *pivot = list_first_entry(head, struct item, list);
list_del(&pivot->list);
struct item *itm = NULL, *is = NULL;
list_for_each_entry_safe (itm, is, head, list) {
if (cmpint(&itm->i, &pivot->i) < 0)
list_move_tail (&itm->list, &list_less);
else
list_move_tail (&itm->list, &list_greater);
}
list_sort(&list_less);
list_sort(&list_greater);
list_add(&pivot->list, head);
list_splice(&list_less, head);
list_splice_tail(&list_greater, head);
}
```
程式首先先把 list 的第一個元素作為 `pivot`
把 `pivot`從 list 移走後走訪 list 的每個元素並且比較
若是比 `pivot` 小則連接到 `list_less` 後面
若是比較大則連接到 `list_greater` 後面
並且用 `list_less` 跟 `list_greater` 分別呼叫 `list_sort` 不斷遞迴下去直到只剩下一項
最後由於 `list_less` 跟 `list_greater` 都已經是排序好的狀態
則我們把 `pivot` 重新加入list
並且把 `list_less` 跟 `list_greater` 分別接到 `pivot` 前後就好
### 測驗 `2`
list Quick Sort (Iterative ver.)
先初始化 `stack` 跟 `partition`
```c
struct list_head stack[MAX_DEPTH];
for (int i = 0; i < MAX_DEPTH; i++)
INIT_LIST_HEAD(&stack[i]);
int top = -1;
list_splice_init(head, &stack[++top]);
struct list_head partition;
INIT_LIST_HEAD(&partition);
```
然後把 `stack` 最上面的 list 取出來丟進 `partition`
```c
list_splice_init(&stack[top--], &partition);
```
接著我們便跟一般的 quick sort一樣
選定第一項元素作為 `pivot`
走訪整個 `partition` 並把比較小的元素丟進 `list_less`
比較大的丟進 `list_greater`
```c
list_for_each_entry_safe (itm, is, &partition, list) {
list_del(&itm->list);
if (cmpint(&itm->i, &pivot->i) < 0)
list_move(&itm->list, &list_less);
else
list_move(&itm->list, &list_greater);
}
```
然後把 `pivot` 接到 `list_less` 後面
最後如果 `list_less` 或是 `list_greater` 不為空就放進 `stack` 裡
```c
list_move_tail (&pivot->list, &list_less);
if (!list_empty(&list_greater))
list_splice_tail(&list_greater, &stack[++top]);
if (!list_empty(&list_less))
list_splice_tail(&list_less, &stack[++top]);
```
如果我們 `stack` 最上面的 list 只剩下一項
則我們就直接把他取出並接在 head 後面
直到 `stack` 最上面的 list 不只一項為止
```c
while (top >= 0 && list_is_singular(&stack[top])) {
struct item *tmp =
list_first_entry(&stack[top], struct item, list);
list_del(&tmp->list);
INIT_LIST_HEAD(&stack[top--]);
list_add_tail(&tmp->list, head);
}
```
### 測驗 `3`
```c
#define XOR_COMP(a, b) ((xor_node_t *) ((uintptr_t) (a)) ^ ((uintptr_t) (b)))
```
```c
int xorlist_add(xor_list_t *list, xor_node_t *n)
{
xor_node_t *real_next;
if (!n)
return ENOMEM;
xor_node_t *real_prev = &list->head;
xor_node_t *node = real_prev->cmp;
if (node == &list->tail)
real_next = &list->tail;
else
real_next = node;
real_prev->cmp = n;
n->cmp = XOR_COMP(real_prev, real_next);
real_next->cmp =
XOR_COMP(n, XOR_COMP(real_prev, real_next->cmp));
list->count++;
return 0;
}
```