Last active
September 15, 2018 01:11
-
-
Save parkj90/853e57ce7f7de4b13acff4e08142b07c to your computer and use it in GitHub Desktop.
queue with doubly linked list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//list.c | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "list.h" | |
struct list { | |
struct node *head; | |
struct node *tail; | |
unsigned int size; | |
}; | |
struct node { | |
struct list *root; | |
struct node *prev; | |
struct node *next; | |
int data; | |
}; | |
//for methods returning int: | |
// 0 - call successful | |
// -1 - out of bounds error | |
// -2 - out of memory error | |
list_t *list_new(void) { | |
list_t *list = malloc(sizeof(list_t)); | |
if (list == NULL) { | |
return NULL; | |
} | |
list->head = NULL; | |
list->tail = NULL; | |
list->size = 0; | |
return list; | |
} | |
node_t *list_append(list_t *list, int value) { | |
if (list == NULL) { | |
return NULL; | |
} | |
//create new end node | |
node_t *node = malloc(sizeof(node_t)); | |
if (node == NULL) { | |
return NULL; | |
} | |
node->root = list; | |
node->next = NULL; | |
node->data = value; | |
//append node | |
if (!list->size) { | |
node->prev = NULL; | |
list->head = node; | |
list->tail = node; | |
} else { | |
list->tail->next = node; | |
node->prev = list->tail; | |
list->tail = node; | |
} | |
list->size++; | |
return node; | |
} | |
node_t *list_search(list_t *list, int value) { | |
if (list == NULL) { | |
return NULL; | |
} | |
node_t *current_node = list->head; | |
while (current_node) { | |
if (current_node->data == value) { | |
return current_node; | |
} | |
current_node = current_node->next; | |
} | |
return NULL; | |
} | |
node_t *list_get_head(list_t *list) { | |
if (list == NULL) { | |
return NULL; | |
} | |
return list->head; | |
} | |
node_t *list_get_tail(list_t *list) { | |
if (list == NULL) { | |
return NULL; | |
} | |
return list->tail; | |
} | |
//insert direction (dir): | |
// true = left of node arg | |
// false = right of node arg | |
int node_insert(node_t *node, int value, bool dir) { | |
if (node == NULL) { | |
return -1; | |
} | |
//create new node | |
node_t *new_node = malloc(sizeof(node_t)); | |
if (new_node == NULL) { | |
return -2; | |
} | |
new_node->root = node->root; | |
new_node->data = value; | |
//insert new node | |
if (dir) { //left insert | |
if (node->prev == NULL) { | |
node->root->head = new_node; | |
new_node->prev = NULL; | |
node->prev = new_node; | |
new_node->next = node; | |
} else { | |
node->prev->next = new_node; | |
new_node->prev = node->prev; | |
node->prev = new_node; | |
new_node->next = node; | |
} | |
} else { //right insert | |
if (node->next == NULL) { | |
node->root->tail = new_node; | |
new_node->next = NULL; | |
node->next = new_node; | |
new_node->prev = node; | |
} else { | |
node->next->prev = new_node; | |
new_node->next = node->next; | |
node->next = new_node; | |
new_node->prev = node; | |
} | |
} | |
node->root->size++; | |
return 0; | |
} | |
int node_delete(node_t *node) { | |
if (node == NULL) { | |
return -1; | |
} | |
if (node->prev == NULL) { | |
node->root->head = node->next; | |
} else { | |
node->prev->next = node->next; | |
} | |
if (node->next == NULL) { | |
node->root->tail = node->prev; | |
} else { | |
node->next->prev = node->prev; | |
} | |
node->root->size--; | |
free(node); | |
return 0; | |
} | |
int node_get(node_t *node, int *value) { | |
if (node == NULL) { | |
return -1; | |
} | |
*value = node->data; | |
return 0; | |
} | |
int node_set(node_t *node, int value) { | |
if (node == NULL) { | |
return -1; | |
} | |
node->data = value; | |
return 0; | |
} | |
unsigned int list_size(list_t *list) { | |
if (list == NULL) { | |
return 0; | |
} | |
return list->size; | |
} | |
//dump direction (dir): | |
// true = left to right | |
// false = right to left | |
void list_dump(list_t *list, bool dir) { | |
if (list == NULL) { | |
return; | |
} | |
node_t *current; | |
if (dir) { | |
current = list->head; | |
while (current) { | |
printf("%d ", current->data); | |
current = current->next; | |
} | |
} else { | |
current = list->tail; | |
while (current) { | |
printf("%d ", current->data); | |
current = current->prev; | |
} | |
} | |
printf("\n"); | |
} | |
void list_free(list_t *list) { | |
if (list == NULL) { | |
return; | |
} | |
if (list->head) { | |
node_t *current = list->head; | |
node_t *temp; | |
while (current) { | |
temp = current->next; | |
free(current); | |
current = temp; | |
} | |
} | |
free(list); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//list.h | |
#include <stdbool.h> | |
typedef struct list list_t; | |
typedef struct node node_t; | |
//for methods returning int: | |
// 0 - call successful | |
// -1 - out of bounds error | |
// -2 - out of memory error | |
list_t *list_new(void); | |
node_t *list_append(list_t *list, int value); | |
node_t *list_search(list_t *list, int value); | |
node_t *list_get_head(list_t *list); | |
node_t *list_get_tail(list_t *list); | |
//insert direction (dir): | |
// true = left of node arg | |
// false = right of node arg | |
int node_insert(node_t *node, int value, bool dir); | |
int node_delete(node_t *node); | |
int node_get(node_t *node, int *value); | |
int node_set(node_t *node, int value); | |
//dump direction (dir): | |
// true = left to right | |
// false = right to left | |
unsigned int list_size(list_t *list); | |
void list_dump(list_t *list, bool dir); | |
void list_free(list_t *list); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//main.c | |
#include <stdio.h> | |
#include <assert.h> | |
#include "queue.h" | |
int main(void) { | |
printf("beginning test of queue...\n"); | |
int value; | |
queue_t *my_queue = queue_new(); | |
if (my_queue == NULL) { | |
printf("failed to allocate queue\n"); | |
return -1; | |
} | |
//test push | |
assert(queue_push(my_queue, 1) == 0); | |
assert(queue_push(my_queue, 2) == 0); | |
assert(queue_push(my_queue, 3) == 0); | |
assert(queue_push(my_queue, 4) == 0); | |
assert(queue_size(my_queue) == 4); | |
assert(queue_empty(my_queue) == false); | |
//test pop and size | |
assert(queue_pop(my_queue, &value) == 0); | |
assert(queue_size(my_queue) == 3); | |
assert(queue_pop(my_queue, &value) == 0); | |
assert(queue_size(my_queue) == 2); | |
assert(queue_pop(my_queue, &value) == 0); | |
assert(queue_size(my_queue) == 1); | |
assert(queue_pop(my_queue, &value) == 0); | |
assert(queue_size(my_queue) == 0); | |
//test empty | |
assert(queue_empty(my_queue)); | |
queue_free(my_queue); | |
printf("all tests passed\n"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//queue.c | |
#include <stdlib.h> | |
#include "queue.h" | |
struct queue{ | |
list_t* list; | |
unsigned int size; | |
}; | |
queue_t *queue_new(void) { | |
queue_t *queue = malloc(sizeof(queue_t)); | |
if (queue == NULL) { | |
return NULL; | |
} | |
queue->list = list_new(); | |
if (queue->list == NULL) { | |
free(queue); | |
return NULL; | |
} | |
queue->size = 0; | |
return queue; | |
} | |
int queue_push(queue_t *queue, int value) { | |
if (queue == NULL) { | |
return -1; | |
} | |
node_t *node = list_append(queue->list, value); | |
if (node == NULL) { | |
return -2; | |
} | |
queue->size++; | |
return 0; | |
} | |
int queue_pop(queue_t *queue, int *value) { | |
if (queue == NULL || !queue->size) { | |
return -1; | |
} | |
if (node_get(list_get_head(queue->list), value)) { | |
return -1; | |
} | |
if (node_delete(list_get_head(queue->list))) { | |
return -1; | |
} | |
queue->size--; | |
return 0; | |
} | |
unsigned int queue_size(queue_t *queue) { | |
if (queue == NULL) { | |
return 0; | |
} | |
return queue->size; | |
} | |
bool queue_empty(queue_t *queue) { | |
if (queue == NULL) { | |
return true; | |
} | |
if (queue->size) { | |
return false; | |
} | |
return true; | |
} | |
void queue_free(queue_t *queue) { | |
if (queue == NULL) { | |
return; | |
} | |
list_free(queue->list); | |
free(queue); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//queue.h | |
#include "list.h" | |
typedef struct queue queue_t; | |
queue_t *queue_new(void); | |
int queue_push(queue_t *queue, int value); | |
int queue_pop(queue_t *queue, int *value); | |
unsigned int queue_size(queue_t *queue); | |
bool queue_empty(queue_t *queue); | |
void queue_free(queue_t *queue); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment