11#include <stdlib.h>
22#include <stdbool.h>
3+ #include <stdio.h>
34#include "dllist.h"
45
56
6-
77typedef struct __doubly_linked_list {
88 dll_node * head ;
99 dll_node * tail ;
@@ -16,7 +16,6 @@ dllist_t dll_init() {
1616 l -> head = NULL ;
1717 l -> tail = NULL ;
1818 l -> elms = 0 ;
19-
2019 return l ;
2120}
2221
@@ -50,31 +49,11 @@ dll_node* dll_last_node(dllist_t l) {
5049}
5150
5251int dll_append (dllist_t l , void * data ) {
53- dll_node * n = calloc (1 , sizeof (dll_node ));
54- if (n == NULL )
55- return DLL_FAILURE ;
56-
57- n -> data = data ;
58- n -> next = NULL ;
59- n -> prev = NULL ;
60-
61- if (l -> elms == 0 ) {
62- l -> tail = n ;
63- l -> head = n ;
64- ++ (l -> elms );
65- return DLL_SUCCESS ;
66- }
67-
68- l -> tail -> next = n ;
69- n -> prev = l -> tail ;
70- l -> tail = n ;
71- ++ (l -> elms );
72-
73- return DLL_SUCCESS ;
52+ return dll_insert (l , data , -1 );
7453}
7554
7655int dll_insert (dllist_t l , void * data , int idx ) {
77- if (idx < 0 && idx <= (-1 * (int )l -> elms ))
56+ if (idx != -1 && idx < 0 && idx <= (-1 * (int )l -> elms ))
7857 return DLL_FAILURE ;
7958
8059 if (idx < 0 )
@@ -89,38 +68,39 @@ int dll_insert(dllist_t l, void * data, int idx) {
8968 n -> next = NULL ;
9069 n -> prev = NULL ;
9170
92- if (idx == 0 ) {
93- n -> next = (l -> head );
71+ if (l -> elms == 0 ) { /* first node to be added edge case */
72+ l -> head = n ;
73+ l -> tail = n ;
74+ } else if (idx == 0 ) { /* first node */
75+ n -> next = l -> head ;
9476 n -> next -> prev = n ;
9577 l -> head = n ;
96- ++ (l -> elms );
97- return DLL_SUCCESS ;
98- } else if (idx >= (int )l -> elms ) {
78+ } else if (idx >= (int )l -> elms ) { /* last node */
9979 l -> tail -> next = n ;
10080 n -> prev = l -> tail ; /* we want the tail to point to the end */
10181 l -> tail = n ;
102- ++ (l -> elms );
103- return DLL_SUCCESS ;
104- }
105-
106- int i ;
107- dll_node * t ;
108- if (idx <= (int )l -> elms / 2 ) {
109- t = dll_first_node (l );
110- for (i = 1 ; i < idx ; i ++ )
111- t = t -> next ;
112- } else {
113- /* start from the tail and go backwards! */
114- int stop = l -> elms - idx ;
115- t = dll_last_node (l );
116- for (i = 0 ; i < stop ; i ++ )
117- t = t -> prev ;
82+ } else { /* mid node; determine which direction would be fastest to get to it */
83+ int i ;
84+ dll_node * t ;
85+ if (idx <= (int )l -> elms / 2 ) {
86+ t = dll_first_node (l );
87+ for (i = 1 ; i < idx ; i ++ )
88+ t = t -> next ;
89+ } else {
90+ /* start from the tail and go backwards! */
91+ int stop = l -> elms - idx ;
92+ t = dll_last_node (l );
93+ for (i = 0 ; i < stop ; i ++ )
94+ t = t -> prev ;
95+ }
96+
97+ n -> next = t -> next ;
98+ t -> next = n ;
99+ n -> next -> prev = n ;
100+ n -> prev = t ;
118101 }
119102
120- n -> next = t -> next ;
121- t -> next = n ;
122- n -> next -> prev = n ;
123- n -> prev = t ;
103+ ++ (l -> elms );
124104 return DLL_SUCCESS ;
125105}
126106
@@ -137,52 +117,39 @@ void* dll_remove(dllist_t l, int idx) {
137117 if (idx < 0 )
138118 idx = l -> elms + idx ;
139119
140- void * ret ;
141- dll_node * n ;
142- if (l -> elms == 1 ) { /* this is the oddest edge case */
143- n = l -> head ;
144- ret = n -> data ;
145- l -> head = NULL ;
146- l -> tail = NULL ;
147- -- l -> elms ;
148- free (n );
149- return ret ;
150- } else if (idx == 0 ) { /* handle edge cases */
151- n = l -> head ;
152- ret = n -> data ;
120+ void * data ;
121+ dll_node * ret ;
122+ if (l -> elms == 1 ) { /* remove the final node */
123+ ret = l -> head ;
124+ l -> head = l -> tail = NULL ;
125+ } else if (idx == 0 ) { /* remove the first node */
126+ ret = l -> head ;
153127 l -> head = l -> head -> next ;
154128 l -> head -> prev = NULL ;
155- -- l -> elms ;
156- free (n );
157- return ret ;
158129 } else if (idx >= (int )(l -> elms - 1 )) {
159- n = l -> tail ;
160- ret = n -> data ;
161- l -> tail = n -> prev ;
162- n -> prev -> next = NULL ;
163- -- l -> elms ;
164- free (n );
165- return ret ;
166- }
167-
168- int i ;
169- if (idx <= (int )l -> elms / 2 ) {
170- n = dll_first_node (l );
171- for (i = 1 ; i < idx ; i ++ )
172- n = n -> next ;
130+ ret = l -> tail ;
131+ l -> tail = ret -> prev ;
132+ ret -> prev -> next = NULL ;
173133 } else {
174- /* start from the tail and go backwards! */
175- int stop = l -> elms - idx ;
176- n = dll_last_node (l );
177- for (i = 0 ; i < stop ; i ++ )
178- n = n -> prev ;
134+ int i ;
135+ if (idx <= (int )l -> elms / 2 ) {
136+ ret = dll_first_node (l );
137+ for (i = 1 ; i < idx ; i ++ )
138+ ret = ret -> next ;
139+ } else {
140+ /* start from the tail and go backwards! */
141+ int stop = l -> elms - idx ;
142+ ret = dll_last_node (l );
143+ for (i = 0 ; i < stop ; i ++ )
144+ ret = ret -> prev ;
145+ }
146+
147+ /* move the nodes before and after's pointers around */
148+ ret -> prev -> next = ret -> next ;
149+ ret -> next -> prev = ret -> prev ;
179150 }
180-
181- /* mode the nodes before and after's pointers around */
182- n -> prev -> next = n -> next ;
183- n -> next -> prev = n -> prev ;
184- ret = n -> data ;
185- -- l -> elms ;
186- free (n );
187- return ret ;
151+ data = ret -> data ;
152+ -- (l -> elms );
153+ free (ret );
154+ return data ;
188155}
0 commit comments