# Facebookc Homework1
## Development Detail
### queue.h
* **q_struct**
* **head** -> the start of the linked list
* **tail** -> use for making $O(1)$ time in insert_tail
```clike=
typedef struct {
list_ele_t *head;
list_ele_t *tail;
int size;
} queue_t;
```
### queue.c
* **q_new**
* create a new queue
* initialize the queue
``` clike=
queue_t *q_new()
{
queue_t *q = malloc(sizeof(queue_t));
if (q == NULL)
return q;
q->head = NULL;
q->tail = q->head;
q->size = 0;
return q;
}
```
* **q_free**
* free the string first then free the node
```clike=
void q_free(queue_t *q)
{
if (q != NULL) {
while (q->head != NULL) {
list_ele_t *tmp = q->head->next;
free(q->head->value);
free(q->head);
q->head = tmp;
}
free(q);
}
}
```
* **q_insert_head**
* Three checking gate to prevent acting on NULL ,empty and lack of memory
* Contents a special case for the insertion when th queue is empty
```clike=
bool q_insert_head(queue_t *q, char *s)
{
if (q == NULL)
return false;
list_ele_t *newh = malloc(sizeof(list_ele_t));
if (newh == NULL) {
free(newh);
return false;
}
char *tmp = malloc(strlen(s) + 1);
if (tmp == NULL) {
free(tmp);
free(newh);
return false;
}
strncpy(tmp, s, strlen(s));
tmp[strlen(s)] = '\0';
if (q->head == NULL) // special case
q->tail = newh;
newh->value = tmp;
newh->next = q->head;
q->head = newh;
q->size = q->size + 1;
return true;
}
```
* **q_insert_tail**
* Three checking gate to prevent acting on NULL ,empty and lack of memory
* Contents a special case for the insertion when queue is empty
```clike=
bool q_insert_tail(queue_t *q, char *s)
{
if (q == NULL)
return false;
list_ele_t *newt = malloc(sizeof(list_ele_t));
if (newt == NULL) {
free(newt);
return false;
}
char *tmp = malloc(strlen(s) + 1);
if (tmp == NULL) {
free(tmp);
free(newt);
return false;
}
strncpy(tmp, s, strlen(s));
tmp[strlen(s)] = '\0';
newt->next = NULL;
newt->value = tmp;
if (q->tail == NULL) { // special case
q->tail = newt;
q->head = newt;
return true;
}
q->tail->next = newt;
q->tail = newt;
q->size = q->size + 1;
return true;
}
```
* **q_remove_head**
* A checking gate for NULL and empty queue
* A checking gate for NULL sp
* free the string first then the node
```clike=
bool q_remove_head(queue_t *q, char *sp, size_t bufsize)
{
if (q == NULL || q->head == NULL)
return false;
if (sp != NULL) {
strncpy(sp, q->head->value, bufsize - 1);
sp[bufsize - 1] = '\0';
}
list_ele_t *tmp = q->head->next;
free(q->head->value);
free(q->head);
q->head = tmp;
q->size = q->size - 1;
return true;
}
```
* **q_size**
* Operate in $O(1)$ time
* A checking gate for NULL and empty queue
```clike=
int q_size(queue_t *q)
{
if (q == NULL || q->head == NULL)
return 0;
return q->size;
}
```
* **q_reverse**
* First check if the queue has at least 2 elements
* Change the direction between each elements
* Break the loop if reach the end (NULL)
```clike=
void q_reverse(queue_t *q)
{
if (q != NULL && q->head != NULL && q->head->next != NULL) {
q->tail = q->head;
list_ele_t *tmp = q->head->next;
list_ele_t *tmp2 = NULL;
q->head->next = NULL;
while (tmp != NULL) {
tmp2 = tmp->next;
tmp->next = q->head;
q->head = tmp;
tmp = tmp2;
}
}
}
```
* **q_sort**
* Add three function to complete the Task
```clike=
void q_sort(queue_t *q)
{
if (q == NULL || q->head == NULL || q->head->next == NULL)
return;
q->head = merge_split(q->head, q->size);
q->tail = merge_find(q->size, q->head);
}
```
* **merge**
* The merging process
* **q1** and **q2** represents two linked list
* Can merge two linked list with diffrent size
* Return a **merged** linked list
* First if_else determine the head of **merged** linked list
```clike=
list_ele_t *merge(list_ele_t *q1, list_ele_t *q2)
{
list_ele_t *leads = NULL, *root;
if (strcmp(q1->value, q2->value) < 0) {
leads = q1;
q1 = q1->next;
} else {
leads = q2;
q2 = q2->next;
}
root = leads;
while (q1 != NULL && q2 != NULL) {
if (strcmp(q1->value, q2->value) < 0) {
leads->next = q1;
q1 = q1->next;
} else {
leads->next = q2;
q2 = q2->next;
}
leads = leads->next;
}
if (q1 == NULL)
leads->next = q2;
else
leads->next = q1;
return root;
}
```
* **merge_find**
* Find the node in specific position
```clike=
list_ele_t *merge_find(int a, list_ele_t *root)
{
while (a > 1) {
root = root->next;
a = a - 1;
}
return root;
}
```
* **merge_split**
* First split the linked list to two linkend list
* The tail points to the NULL
* Do the merge-sort to the two linked list
* Recursively , return root if it has only ine elements
* Finally merge the two linked list to one
* Return the **merged-sorted** linked list
```clike=
list_ele_t *merge_split(list_ele_t *root, int size)
{
if (size / 2 > 0) {
list_ele_t *tmp = merge_find(size / 2, root);
list_ele_t *q2 = tmp->next;
tmp->next = NULL;
root = merge_split(root, size / 2);
q2 = merge_split(q2, size - size / 2);
return merge(root, q2);
} else {
root->next = NULL;
return root;
}
}
```