summaryrefslogtreecommitdiff
path: root/Algorithms/linked_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'Algorithms/linked_list.c')
-rw-r--r--Algorithms/linked_list.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/Algorithms/linked_list.c b/Algorithms/linked_list.c
new file mode 100644
index 0000000..16bf24b
--- /dev/null
+++ b/Algorithms/linked_list.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) Carlos Maiolino <[email protected]>.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ /* This is a simple example of double linked lists I wrote for fun
+ * Because I had nothing better to do :)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+struct list_item {
+ int key;
+ struct list_item *prev;
+ struct list_item *next;
+};
+
+struct list_item *list_add(struct list_item *HEAD, int key)
+{
+ struct list_item *item = malloc(sizeof(struct list_item));
+
+ if (!item)
+ goto err_out;
+
+ item->key = key;
+ item->prev = NULL;
+
+ /* list is empty, just asign this item as HEAD */
+ if (!HEAD) {
+ item->next = NULL;
+ HEAD = item;
+ return HEAD;
+ }
+
+ item->next = HEAD;
+ HEAD->prev = item;
+ HEAD = item;
+ return HEAD;
+
+err_out:
+ return NULL;
+}
+
+void list_del_by_item(struct list_item **HEAD, int i)
+{
+ struct list_item *item = *HEAD;
+
+ for (; i > 0; i--) {
+ if (item) {
+ item = item->next;
+ } else {
+ printf("Can't free an inexistent item\n");
+ return;
+ }
+ }
+
+ /* if this is the last item, item->next is already NULL */
+ if (item->prev)
+ item->prev->next = item->next;
+ else {
+ *HEAD = item->next;
+ }
+
+ if (item->next)
+ item->next->prev = item->prev;
+
+ free(item);
+ return;
+}
+/*
+int list_del_by_key(list, key)
+int list_search(list, key)
+*/
+
+void print_list(struct list_item *HEAD)
+{
+ struct list_item *iter = HEAD;
+
+ if (!HEAD) {
+ printf("List is empty\n");
+ return;
+ }
+
+ if (HEAD->prev != NULL) {
+ printf("Item is not the head of the list\n");
+ return;
+ }
+
+ while (iter) {
+ printf(" %d", iter->key);
+ iter = iter->next;
+ }
+ printf("\nEND OF LIST\n");
+}
+
+void print_node(struct list_item *item)
+{
+ int *val = &(item->key);
+ printf("NODE= %p \n", item);
+ printf(" .prev = %p\n", item->prev);
+ printf(" .next = %p\n", item->next);
+ printf(" .key = %p\n", &(item->key));
+ printf(" .key = %d\n", *(&(item->key)));
+ printf(" .key = %d\n", *val);
+}
+
+void debug_list(struct list_item *HEAD)
+{
+ while (HEAD) {
+ print_node(HEAD);
+ HEAD = HEAD->next;
+ }
+}
+
+int main(void)
+{
+ /* Init list head */
+ struct list_item *HEAD = NULL;
+ int val;
+ char cmd;
+
+ while (1) {
+ printf("Select option: ");
+ scanf(" %c", &cmd);
+
+ switch (cmd) {
+ case 'a':
+ printf("Add value: ");
+ scanf(" %d", &val);
+ HEAD = list_add(HEAD, val);
+ break;
+ case 'd':
+ printf("Item to delete (starting on 0): ");
+ scanf(" %d", &val);
+ if (HEAD)
+ list_del_by_item(&HEAD, val);
+ else
+ printf("List is empty\n");
+ break;
+
+ case 'p':
+ print_list(HEAD);
+ break;
+ case 'D':
+ debug_list(HEAD);
+ break;
+ case 'q':
+ goto out;
+ default:
+ printf("a: add to list, d: del item, p: print\n");
+ break;
+ }
+ }
+
+out:
+ while (HEAD) {
+ struct list_item *next = HEAD->next;
+ free(HEAD);
+ HEAD = next;
+ }
+
+ return 0;
+}