# 2020q3 Homework1 (quiz1)
contributed by guaneec
###### tags: `sysprog2020`
## Q1 - Linked list
```C
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct __node {
int value;
struct __node *next;
} node_t;
void add_entry(node_t **head, int new_value)
{
node_t **indirect = head;
node_t *new_node = malloc(sizeof(node_t));
new_node->value = new_value;
new_node->next = NULL;
// AA1;
assert(new_node);
while (*indirect)
indirect = &(*indirect)->next;
// AA2;
*indirect = new_node;
}
node_t *find_entry(node_t *head, int value)
{
node_t *current = head;
for (; current && current->value != value; current = current->next)
/* interate */;
return current;
}
void remove_entry(node_t **head, node_t *entry)
{
node_t **indirect = head;
while ((*indirect) != entry)
indirect = &(*indirect)->next;
*indirect = entry->next;
free(entry);
}
node_t *swap_pair(node_t *head)
{
for (node_t **node = &head; *node && (*node)->next; /* BB1 */
node = &(*node)->next->next) {
node_t *tmp = *node;
/* BB2 */
*node = (*node)->next;
tmp->next = (*node)->next;
(*node)->next = tmp;
}
return head;
}
node_t *reverse(node_t *head)
{
node_t *cursor = NULL;
while (head) {
node_t *next = head->next;
// CCC;
head->next = cursor;
cursor = head;
head = next;
}
return cursor;
}
void print_list(node_t *head)
{
for (node_t *current = head; current; current = current->next)
printf("%d ", current->value);
printf("\n");
}
int main(int argc, char const *argv[])
{
node_t *head = NULL;
print_list(head);
add_entry(&head, 72);
add_entry(&head, 101);
add_entry(&head, 108);
add_entry(&head, 109);
add_entry(&head, 110);
add_entry(&head, 111);
print_list(head);
node_t *entry = find_entry(head, 101);
remove_entry(&head, entry);
entry = find_entry(head, 111);
remove_entry(&head, entry);
print_list(head);
/* swap pair.
* See https://leetcode.com/problems/swap-nodes-in-pairs/
*/
head = swap_pair(head);
print_list(head);
head = reverse(head);
print_list(head);
return 0;
}
```
### Q1.1 - Explanation
### Q1.2 - Change function signature
Make `swap_pair` and `reverse` return void instead
[Diff](https://github.com/guaneec/sysprog-2020q3-quiz1/commit/cd9470d59fbbc3013585af7a4608106197a6628d)
### Q1.3 - Recursive reverse
```C
void reverse(node_t **head)
{
if (!*head)
return;
node_t *tmp = (*head)->next;
if (!tmp) return;
reverse(&(*head)->next);
tmp->next = (*head);
tmp = (*head)->next;
(*head)->next = NULL;
*head = tmp;
}
```
### Q1.4 - Fisher-Yates shuffle
```C
int length(node_t *head) {
int l = 0;
for (; head; head = head->next) ++l;
return l;
}
void shuffle(node_t **head) {
node_t tmpheadnew;
node_t tmpheadold = {.next = *head};
node_t *tail = &tmpheadnew;
for (int l = length(*head); l > 0; --l) {
// pick a random remaining node
int r = rand() % l;
node_t *cursor = &tmpheadold;
for (int i = 0; i < r; ++i) {
cursor = cursor->next;
}
// append node to new list and remove from old list
tail->next = cursor->next;
tail = tail->next;
cursor->next = cursor->next->next;
}
*head = tmpheadnew.next;
}
```