Skip to content

Instantly share code, notes, and snippets.

@parkj90
Last active September 15, 2018 01:11
Show Gist options
  • Save parkj90/853e57ce7f7de4b13acff4e08142b07c to your computer and use it in GitHub Desktop.
Save parkj90/853e57ce7f7de4b13acff4e08142b07c to your computer and use it in GitHub Desktop.
queue with doubly linked list
//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);
}
//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);
//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");
}
//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);
}
//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