aboutsummaryrefslogtreecommitdiff
path: root/sem3/algo/mm2/linked/llist.c
blob: 8044e0b61d0e379b54519da146a2e86761bbedd0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "llist.h"

#include <string.h>
#include <stdio.h>


#define OUT_OFF_BOUNDS 2

void llist_init(llist_t *list)
{
	/* Zero out structure */
	list->head = list->root = NULL;

	list->len = 0;

}

void llist_append(llist_t *list, int val)
{
	/* Insert node after HEAD */
	list->head = node_insert(list->head, val);

	/* Check if was list is empty */
	if ( list->len == 0 ) {
		/* Set root */
		list->root = list->head;
	}

	/* Increase count */
	list->len++;
}

node_t *llist_get_node(llist_t *list, unsigned int index)
{
	/* Check if we have it */
	if ( index >= list->len ) {
		return NULL;
	}

	/* Find the best way to go down the list */
	int direc = index > (list->len / 2) ? -1 : 1;

	/* Setup start location */
	int pos = direc > 0 ? 0 : list->len-1;
	node_t *node = direc > 0 ? list->root : list->head;
	
	/* Go to index */
	while ( pos != index ) {
		/* TODO kinda risky, we trust our math and len */
		node = direc > 0 ? node->next : node->prev;

		pos += direc;
	}

	return node;
}

int llist_get(llist_t *list, unsigned int index)
{
	/* Get node */
	node_t *node = llist_get_node(list, index);
	if ( node == NULL ) {
		/* Yes i know this is stupid */
		return -1;
	}

	/* Return value */
	return node->val;
}


int llist_pop(llist_t *list, unsigned int index)
{
	/* Get node */
	node_t *node = llist_get_node(list, index);
	if ( node == NULL ) {
		/* Yes i know this is stupid */
		return -1;
	}

	/* Update root and head if we delete it */
	if ( node == list->root ) {
		list->root = node->next;
	}
	if ( node == list->head ) {
		list->head = node->prev;
	}
	
	/* Keep len up to date */
	list->len--;

	/* Delete stuff */
	return node_pop(node);
}