Commit 6ccdccb
Changed files (7)
src/01/02b/README.md
@@ -8,6 +8,7 @@ Student ID: 3431709
Swap two adjacent elements in a list by adjusting only the links (and not the data) using doubly-linked list.
## Description of the Code
+
## Errors and Warnings
```bash
src/01/05/doubly_linked_list.c
@@ -0,0 +1,93 @@
+#include "doubly_linked_list.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+Node *initialize(int data) {
+ Node *node = malloc(sizeof(Node));
+ node->data = data;
+ node->next = NULL;
+ node->prev = NULL;
+ return node;
+}
+
+Node *add(Node *head, int data) {
+ Node *tail;
+ Node *tmp = head;
+
+ while(tmp) {
+ if (!tmp->next)
+ break;
+ tmp = tmp->next;
+ }
+ tail = tmp;
+ tail->next = initialize(data);
+ tail->next->prev = tail;
+ return tail->next;
+}
+
+Node *get(Node *from, int index) {
+ if (!from || index < 0) return NULL;
+
+ while(index > 0 && from){
+ from = from->next;
+ index--;
+ }
+ return from;
+}
+
+static int size(Node *head) {
+ int i = 0;
+ for (Node *tmp = head; tmp && tmp != NULL; tmp = tmp->next) i++;
+ return i;
+}
+
+static void assign_next(Node *self, Node *other) {
+ if (self)
+ self->next = other;
+
+ if (other)
+ other->prev = self;
+}
+
+static void assign_prev(Node *self, Node *other) {
+ if (self)
+ self->prev = other;
+
+ if (other)
+ other->next = self;
+}
+
+Node *reverse(Node *head) {
+ Node *tmp = NULL;
+ Node *current = head;
+
+ while (current != NULL) {
+ tmp = current->prev;
+ current->prev = current->next;
+ current->next = tmp;
+ current = current->prev;
+ }
+ return tmp ? tmp->prev : head;
+}
+
+static void print(Node *node) {
+ if (node->prev && node->next)
+ printf("(%d<%d>%d)", node->prev->data, node->data, node->next->data);
+ else if (node->next)
+ printf("(nil<%d>%d)", node->data, node->next->data);
+ else
+ printf("(%d<%d>nil)", node->prev->data, node->data);
+}
+
+void inspect(Node *node) {
+ if (!node) return;
+
+ printf("[ ");
+ while (node) {
+ print(node);
+ printf(" ");
+ node = node->next;
+ }
+ printf("]\n");
+}
+
src/01/05/doubly_linked_list.h
@@ -0,0 +1,13 @@
+struct node {
+ int data;
+ struct node *next;
+ struct node *prev;
+};
+
+typedef struct node Node;
+
+Node *initialize(int data);
+Node *add(Node *head, int data);
+Node *get(Node *from, int index);
+Node *reverse(Node *head);
+void inspect(Node *node);
src/01/05/doubly_linked_list_test.c
@@ -0,0 +1,448 @@
+#include <cgreen/cgreen.h>
+#include "doubly_linked_list.h"
+
+Describe(DoublyLinkedList);
+BeforeEach(DoublyLinkedList){ }
+AfterEach(DoublyLinkedList){ }
+
+Ensure(DoublyLinkedList, when_getting_head) {
+ Node *head = initialize(100);
+ assert_that(get(head, 0), is_equal_to(head));
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_getting_mid) {
+ Node *head = initialize(100);
+
+ Node *mid = add(head, 200);
+ add(head, 300);
+
+ assert_that(get(head, 1), is_equal_to(mid));
+ assert_that(get(head, 1)->data, is_equal_to(200));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_getting_tail) {
+ Node *head = initialize(100);
+
+ add(head, 200);
+ Node *tail = add(head, 300);
+
+ assert_that(get(head, 2), is_equal_to(tail));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_getting_from_empty_list) {
+ assert_that(get(NULL, 2), is_equal_to(NULL));
+}
+
+Ensure(DoublyLinkedList, when_getting_negative_index) {
+ Node *head = initialize(100);
+
+ assert_that(get(head, -1), is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_getting_index_out_of_range) {
+ Node *head = initialize(100);
+
+ assert_that(get(head, 1), is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_head_with_non_adjacent_node) {
+ Node *head = initialize(100);
+ Node *mid1 = add(head, 200);
+ Node *mid2 = add(head, 300);
+ Node *tail = add(head, 400);
+
+ swap(head, mid2);
+
+ assert_that(head->prev, is_equal_to(mid1));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(tail));
+
+ assert_that(mid1->prev, is_equal_to(mid2));
+ assert_that(mid1->data, is_equal_to(200));
+ assert_that(mid1->next, is_equal_to(head));
+
+ assert_that(mid2->prev, is_equal_to(NULL));
+ assert_that(mid2->data, is_equal_to(300));
+ assert_that(mid2->next, is_equal_to(mid1));
+
+ assert_that(tail->prev, is_equal_to(head));
+ assert_that(tail->data, is_equal_to(400));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_head_with_non_adjacent_node_inverted) {
+ Node *head = initialize(100);
+ Node *mid1 = add(head, 200);
+ Node *mid2 = add(head, 300);
+ Node *tail = add(head, 400);
+
+ swap(mid2, head);
+
+ assert_that(head->prev, is_equal_to(mid1));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(tail));
+
+ assert_that(mid1->prev, is_equal_to(mid2));
+ assert_that(mid1->data, is_equal_to(200));
+ assert_that(mid1->next, is_equal_to(head));
+
+ assert_that(mid2->prev, is_equal_to(NULL));
+ assert_that(mid2->data, is_equal_to(300));
+ assert_that(mid2->next, is_equal_to(mid1));
+
+ assert_that(tail->prev, is_equal_to(head));
+ assert_that(tail->data, is_equal_to(400));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_head_adjacent) {
+ Node *head = initialize(100);
+ Node *mid = add(head, 200);
+ Node *tail = add(head, 300);
+
+ swap(head, mid);
+
+ assert_that(head->prev, is_equal_to(mid));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(tail));
+
+ assert_that(mid->prev, is_equal_to(NULL));
+ assert_that(mid->data, is_equal_to(200));
+ assert_that(mid->next, is_equal_to(head));
+
+ assert_that(tail->prev, is_equal_to(head));
+ assert_that(tail->data, is_equal_to(300));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_head_adjacent_inverted) {
+ Node *head = initialize(100);
+ Node *mid = add(head, 200);
+ Node *tail = add(head, 300);
+
+ swap(mid, head);
+
+ assert_that(head->prev, is_equal_to(mid));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(tail));
+
+ assert_that(mid->prev, is_equal_to(NULL));
+ assert_that(mid->data, is_equal_to(200));
+ assert_that(mid->next, is_equal_to(head));
+
+ assert_that(tail->prev, is_equal_to(head));
+ assert_that(tail->data, is_equal_to(300));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_mid) {
+ Node *head = initialize(100);
+ Node *mid1 = add(head, 200);
+ Node *mid2 = add(head, 300);
+ Node *mid3 = add(head, 400);
+ Node *tail = add(head, 500);
+
+ swap(mid1, mid3);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(mid3));
+
+ assert_that(mid1->prev, is_equal_to(mid2));
+ assert_that(mid1->data, is_equal_to(200));
+ assert_that(mid1->next, is_equal_to(tail));
+
+ assert_that(mid2->prev, is_equal_to(mid3));
+ assert_that(mid2->data, is_equal_to(300));
+ assert_that(mid2->next, is_equal_to(mid1));
+
+ assert_that(mid3->prev, is_equal_to(head));
+ assert_that(mid3->data, is_equal_to(400));
+ assert_that(mid3->next, is_equal_to(mid2));
+
+ assert_that(tail->prev, is_equal_to(mid1));
+ assert_that(tail->data, is_equal_to(500));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_y_mid) {
+ Node *head = initialize(100);
+ Node *mid1 = add(head, 200);
+ Node *mid2 = add(head, 300);
+ Node *mid3 = add(head, 400);
+ Node *tail = add(head, 500);
+
+ swap(mid3, mid1);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(mid3));
+
+ assert_that(mid1->prev, is_equal_to(mid2));
+ assert_that(mid1->data, is_equal_to(200));
+ assert_that(mid1->next, is_equal_to(tail));
+
+ assert_that(mid2->prev, is_equal_to(mid3));
+ assert_that(mid2->data, is_equal_to(300));
+ assert_that(mid2->next, is_equal_to(mid1));
+
+ assert_that(mid3->prev, is_equal_to(head));
+ assert_that(mid3->data, is_equal_to(400));
+ assert_that(mid3->next, is_equal_to(mid2));
+
+ assert_that(tail->prev, is_equal_to(mid1));
+ assert_that(tail->data, is_equal_to(500));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_mid_adjacent) {
+ Node *head = initialize(100);
+ Node *mid1 = add(head, 200);
+ Node *mid2 = add(head, 300);
+ Node *tail = add(head, 400);
+
+ swap(mid1, mid2);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(mid2));
+
+ assert_that(mid1->prev, is_equal_to(mid2));
+ assert_that(mid1->data, is_equal_to(200));
+ assert_that(mid1->next, is_equal_to(tail));
+
+ assert_that(mid2->prev, is_equal_to(head));
+ assert_that(mid2->data, is_equal_to(300));
+ assert_that(mid2->next, is_equal_to(mid1));
+
+ assert_that(tail->prev, is_equal_to(mid1));
+ assert_that(tail->data, is_equal_to(400));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_mid_adjacent_y) {
+ Node *head = initialize(100);
+ Node *mid1 = add(head, 200);
+ Node *mid2 = add(head, 300);
+ Node *tail = add(head, 400);
+
+ swap(mid2, mid1);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(mid2));
+
+ assert_that(mid1->prev, is_equal_to(mid2));
+ assert_that(mid1->data, is_equal_to(200));
+ assert_that(mid1->next, is_equal_to(tail));
+
+ assert_that(mid2->prev, is_equal_to(head));
+ assert_that(mid2->data, is_equal_to(300));
+ assert_that(mid2->next, is_equal_to(mid1));
+
+ assert_that(tail->prev, is_equal_to(mid1));
+ assert_that(tail->data, is_equal_to(400));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_tail_adjacent) {
+ Node *head = initialize(100);
+ Node *mid = add(head, 200);
+ Node *tail = add(head, 300);
+
+ swap(mid, tail);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(tail));
+
+ assert_that(mid->prev, is_equal_to(tail));
+ assert_that(mid->data, is_equal_to(200));
+ assert_that(mid->next, is_equal_to(NULL));
+
+ assert_that(tail->prev, is_equal_to(head));
+ assert_that(tail->data, is_equal_to(300));
+ assert_that(tail->next, is_equal_to(mid));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_tail_adjacent_inverted) {
+ Node *head = initialize(100);
+ Node *mid = add(head, 200);
+ Node *tail = add(head, 300);
+
+ swap(tail, mid);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(tail));
+
+ assert_that(mid->prev, is_equal_to(tail));
+ assert_that(mid->data, is_equal_to(200));
+ assert_that(mid->next, is_equal_to(NULL));
+
+ assert_that(tail->prev, is_equal_to(head));
+ assert_that(tail->data, is_equal_to(300));
+ assert_that(tail->next, is_equal_to(mid));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_tail_with_non_adjacent_node) {
+ Node *head = initialize(100);
+ Node *mid1 = add(head, 200);
+ Node *mid2 = add(head, 300);
+ Node *tail = add(head, 400);
+
+ swap(mid1, tail);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(tail));
+
+ assert_that(mid1->prev, is_equal_to(mid2));
+ assert_that(mid1->data, is_equal_to(200));
+ assert_that(mid1->next, is_equal_to(NULL));
+
+ assert_that(mid2->prev, is_equal_to(tail));
+ assert_that(mid2->data, is_equal_to(300));
+ assert_that(mid2->next, is_equal_to(mid1));
+
+ assert_that(tail->prev, is_equal_to(head));
+ assert_that(tail->data, is_equal_to(400));
+ assert_that(tail->next, is_equal_to(mid2));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_tail_with_non_adjacent_node_inverted) {
+ Node *head = initialize(100);
+ Node *mid1 = add(head, 200);
+ Node *mid2 = add(head, 300);
+ Node *tail = add(head, 400);
+
+ swap(tail, mid1);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(tail));
+
+ assert_that(mid1->prev, is_equal_to(mid2));
+ assert_that(mid1->data, is_equal_to(200));
+ assert_that(mid1->next, is_equal_to(NULL));
+
+ assert_that(mid2->prev, is_equal_to(tail));
+ assert_that(mid2->data, is_equal_to(300));
+ assert_that(mid2->next, is_equal_to(mid1));
+
+ assert_that(tail->prev, is_equal_to(head));
+ assert_that(tail->data, is_equal_to(400));
+ assert_that(tail->next, is_equal_to(mid2));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_with_NULL) {
+ Node *head = initialize(100);
+ Node *mid = add(head, 200);
+ Node *tail = add(head, 300);
+
+ swap(mid, NULL);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+ assert_that(head->next, is_equal_to(mid));
+
+ assert_that(mid->prev, is_equal_to(head));
+ assert_that(mid->data, is_equal_to(200));
+ assert_that(mid->next, is_equal_to(tail));
+
+ assert_that(tail->prev, is_equal_to(mid));
+ assert_that(tail->data, is_equal_to(300));
+ assert_that(tail->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_swapping_self) {
+ Node *head = initialize(100);
+ Node *mid = add(head, 200);
+ Node *tail = add(head, 300);
+
+ swap(mid, mid);
+
+ assert_that(head->prev, is_equal_to(NULL));
+ assert_that(head->data, is_equal_to(100));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_reversing_a_short_list) {
+ Node *head = initialize(100);
+ Node *mid = add(head, 200);
+ Node *tail = add(head, 300);
+
+ Node *new_head = reverse(head);
+
+ assert_that(new_head->prev, is_equal_to(NULL));
+ assert_that(new_head, is_equal_to(tail));
+ assert_that(new_head->next, is_equal_to(mid));
+
+ assert_that(mid->prev, is_equal_to(tail));
+ assert_that(mid->next, is_equal_to(head));
+
+ assert_that(head->prev, is_equal_to(mid));
+ assert_that(head->next, is_equal_to(NULL));
+
+ free(head);
+}
+
+Ensure(DoublyLinkedList, when_reversing_an_empty_list) {
+ Node *head = initialize(100);
+ Node *result = reverse(head);
+
+ assert_that(result, is_equal_to(head));
+
+ free(head);
+}
+
+TestSuite *reverse_doubly_linked_list_tests() {
+ TestSuite *suite = create_test_suite();
+
+ add_test_with_context(suite, DoublyLinkedList, when_reversing_a_short_list);
+ add_test_with_context(suite, DoublyLinkedList, when_reversing_an_empty_list);
+
+ return suite;
+}
+
+int main(int argc, char **argv) {
+ TestSuite *suite = create_test_suite();
+ add_suite(suite, reverse_doubly_linked_list_tests());
+ return run_test_suite(suite, create_text_reporter());
+}
src/01/05/main.c
@@ -0,0 +1,34 @@
+#include "doubly_linked_list.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int next(void) {
+ return rand() % 100;
+}
+
+int main(int argc, char *argv[])
+{
+ printf("=== COMP-272 - Assignment 1 - Question 2b ===\n");
+ Node *head = initialize(next());
+ Node *new_head = NULL;
+
+ for (int i = 0; i < 9; ++i)
+ add(head, next());
+
+ printf("\t");
+ inspect(head);
+
+ new_head = get(head, 1);
+ swap(head, new_head);
+ head = new_head;
+ printf("swap: 0,1\n\t");
+ inspect(head);
+
+ for (int i = 2; i < 10; i+=2) {
+ swap(get(head, i), get(head, i + 1));
+ printf("swap: %d,%d\n\t", i, i + 1);
+ inspect(head);
+ }
+
+ return 0;
+}
src/01/05/Makefile
@@ -0,0 +1,37 @@
+#!/usr/bin/make -f
+SHELL=/bin/sh
+
+CC=clang
+TEST_LIBS = -lcgreen
+
+BUILDDIR := build
+OBJS := $(addprefix $(BUILDDIR)/,doubly_linked_list.o)
+TEST_OBJS := $(addprefix $(BUILDDIR)/,doubly_linked_list_test.o)
+
+$(BUILDDIR)/%.o : %.c
+ $(COMPILE.c) $(OUTPUT_OPTION) $<
+
+.PHONY: all
+all: $(OBJS) $(BUILDDIR)/main.o
+ $(CC) $(OBJS) $(BUILDDIR)/main.o -o $(BUILDDIR)/program
+
+.PHONY: test
+test: $(OBJS) $(TEST_OBJS)
+ $(CC) $(OBJS) $(TEST_OBJS) $(TEST_LIBS) -o $(BUILDDIR)/test
+
+$(OBJS): | $(BUILDDIR)
+
+$(TEST_OBJS): | $(BUILDDIR)
+
+$(BUILDDIR):
+ mkdir $(BUILDDIR)
+
+.PHONY: clean
+clean:
+ rm -fr build
+
+run : all
+ ./build/program
+
+run_test : test
+ cgreen-runner -c -v $(BUILDDIR)/test
src/01/05/README.md
@@ -0,0 +1,13 @@
+# Learning Profile for Assignment #1 - Question #05 - Computer Science 272: Data Structures and Algorithms
+
+Name: Mo Khan
+Student ID: 3431709
+
+## Problem Statement
+
+Write a method, reverse(), that reverses the order of elements in a DLList.
+
+## Description of the Code
+## Errors and Warnings
+## Sample Input and Output
+## Discussion