Algorithms_in_C 1.0.0
Set of algorithms implemented in C.
Loading...
Searching...
No Matches
circular_doubly_linked_list.c File Reference
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
Include dependency graph for circular_doubly_linked_list.c:

Data Structures

struct  node
 Node, the basic data structure in the tree. More...
 

Typedefs

typedef struct node ListNode
 to verify assumptions made by the program and print a diagnostic message if this assumption is false.
 

Functions

ListNodecreate_node (uint64_t data)
 Create a list node.
 
ListNodeinsert_at_head (ListNode *head, uint64_t data)
 Insert a node at start of list.
 
ListNodeinsert_at_tail (ListNode *head, uint64_t data)
 Insert a node at end of list.
 
ListNodedelete_from_head (ListNode *head)
 Function for deletion of the first node in list.
 
ListNodedelete_from_tail (ListNode *head)
 Function for deletion of the last node in list.
 
int getsize (ListNode *head)
 The function that will return current size of list.
 
void display_list (ListNode *head)
 Display list function.
 
uint64_t get (ListNode *list, const int index)
 access the list by index
 
static void test ()
 Self-test implementations.
 
int main ()
 Main function.
 

Detailed Description

Circular Doubly Linked List combines the properties of a doubly linked list and a circular linked list in which two consecutive elements are linked or connected by the previous. Next, the pointer and the last node point to the first node via the next pointer, and the first node points to the last node via the previous pointer.

In this implementation, functions to insert at the head, insert at the last index, delete the first node, delete the last node, display list, and get list size functions are coded.

Author
Sahil Kandhare

Typedef Documentation

◆ ListNode

typedef struct node ListNode

to verify assumptions made by the program and print a diagnostic message if this assumption is false.

to provide a set of integer types with universally consistent definitions that are operating system-independent for IO operations for including functions involving memory allocation such as malloc

Circular Doubly linked list struct

Function Documentation

◆ create_node()

ListNode * create_node ( uint64_t  data)

Create a list node.

Parameters
datathe data that the node initialises with
Returns
ListNode* pointer to the newly created list node
40{
41 ListNode *new_list = (ListNode *)malloc(sizeof(ListNode));
42 new_list->value = data;
43 new_list->next = new_list;
44 new_list->prev = new_list;
45 return new_list;
46}
#define malloc(bytes)
This macro replace the standard malloc function with malloc_dbg.
Definition malloc_dbg.h:18
Definition prime_factoriziation.c:25
Node, the basic data structure in the tree.
Definition binary_search_tree.c:15
struct node * next
List pointers.
Definition bfs.c:24
uint64_t value
Data stored on each node.
Definition circular_doubly_linked_list.c:31

◆ delete_from_head()

ListNode * delete_from_head ( ListNode head)

Function for deletion of the first node in list.

Parameters
headstart pointer of list
Returns
ListNode* pointer to the list node after deleting first node
112{
113 if (head == NULL)
114 {
115 printf("The list is empty\n");
116 return head;
117 }
118 ListNode *temp1, *temp2;
119 temp1 = head;
120 temp2 = temp1->prev;
121 if (temp1 == temp2)
122 {
123 free(temp2);
124 head = NULL;
125 return head;
126 }
127 temp2->next = temp1->next;
128 (temp1->next)->prev = temp2;
129 head = temp1->next;
130 free(temp1);
131 return head;
132}
#define free(ptr)
This macro replace the standard free function with free_dbg.
Definition malloc_dbg.h:26

◆ delete_from_tail()

ListNode * delete_from_tail ( ListNode head)

Function for deletion of the last node in list.

Parameters
headstart pointer of list
Returns
ListNode* pointer to the list node after deleting first node
141{
142 if (head == NULL)
143 {
144 printf("The list is empty\n");
145 return head;
146 }
147
148 ListNode *temp1, *temp2;
149 temp1 = head;
150 temp2 = temp1->prev;
151 if (temp1 == temp2)
152 {
153 free(temp2);
154 head = NULL;
155 return head;
156 }
157 (temp2->prev)->next = temp1;
158 temp1->prev = temp2->prev;
159 free(temp2);
160 return head;
161}
int next(Vector *vec)
This function gets the next item from the Vector each time it's called.
Definition vector.c:102
Here is the call graph for this function:

◆ display_list()

void display_list ( ListNode head)

Display list function.

Parameters
headstart pointer of list
Returns
void
192{
193 printf("\nContents of your linked list: ");
194 ListNode *temp;
195 temp = head;
196 if (head != NULL)
197 {
198 while (temp->next != head)
199 {
200 printf("%" PRIu64 " <-> ", temp->value);
201 temp = temp->next;
202 }
203 if (temp->next == head)
204 {
205 printf("%" PRIu64, temp->value);
206 }
207 }
208 else
209 {
210 printf("The list is empty");
211 }
212 printf("\n");
213}

◆ get()

uint64_t get ( ListNode list,
const int  index 
)

access the list by index

Parameters
listpointer to the target list
indexaccess location
Returns
the value at the specified index, wrapping around if the index is larger than the size of the target list
224{
225 if (list == NULL || index < 0)
226 {
227 exit(EXIT_FAILURE);
228 }
229 ListNode *temp = list;
230 for (int i = 0; i < index; ++i)
231 {
232 temp = temp->next;
233 }
234 return temp->value;
235}
Doubly linked list struct.
Definition doubly_linked_list.c:24

◆ getsize()

int getsize ( ListNode head)

The function that will return current size of list.

Parameters
headstart pointer of list
Returns
int size of list
170{
171 if (!head)
172 {
173 return 0;
174 }
175 int size = 1;
176 ListNode *temp = head->next;
177 while (temp != head)
178 {
179 temp = temp->next;
180 size++;
181 }
182 return size;
183}

◆ insert_at_head()

ListNode * insert_at_head ( ListNode head,
uint64_t  data 
)

Insert a node at start of list.

Parameters
headstart pointer of list
datathe data that the node initialises with
Returns
ListNode* pointer to the newly created list node inserted at the head
56{
57 if (head == NULL)
58 {
59 head = create_node(data);
60 return head;
61 }
62 else
63 {
64 ListNode *temp;
65 ListNode *new_node = create_node(data);
66 temp = head->prev;
67 new_node->next = head;
68 head->prev = new_node;
69 new_node->prev = temp;
70 temp->next = new_node;
71 head = new_node;
72 return head;
73 }
74}
ListNode * create_node(uint64_t data)
Create a list node.
Definition circular_doubly_linked_list.c:39
Here is the call graph for this function:

◆ insert_at_tail()

ListNode * insert_at_tail ( ListNode head,
uint64_t  data 
)

Insert a node at end of list.

Parameters
headstart pointer of list
datathe data that the node initialises with
Returns
ListNode* pointer to the newly added list node that was inserted at the head of list.
85{
86 if (head == NULL)
87 {
88 head = create_node(data);
89 return head;
90 }
91 else
92 {
93 ListNode *temp1, *temp2;
94 ListNode *new_node = create_node(data);
95 temp1 = head;
96 temp2 = head->prev;
97 new_node->prev = temp2;
98 new_node->next = temp1;
99 temp1->prev = new_node;
100 temp2->next = new_node;
101 return head;
102 }
103}
Here is the call graph for this function:

◆ main()

int main ( void  )

Main function.

Returns
0 on exit
301{
302 test(); // run self-test implementations
303 return 0;
304}
static void test()
Self-test implementations.
Definition circular_doubly_linked_list.c:241
Here is the call graph for this function:

◆ test()

static void test ( void  )
static

Self-test implementations.

Returns
void
242{
243 ListNode *testList = NULL;
244 unsigned int array[] = {2, 3, 4, 5, 6};
245
246 assert(getsize(testList) == 0);
247
248 printf("Testing inserting elements:\n");
249 for (int i = 0; i < 5; ++i)
250 {
251 display_list(testList);
252 testList = insert_at_head(testList, array[i]);
253 assert(testList->value == array[i]);
254 assert(getsize(testList) == i + 1);
255 }
256
257 printf("\nTesting removing elements:\n");
258 for (int i = 4; i > -1; --i)
259 {
260 display_list(testList);
261 assert(testList->value == array[i]);
262 testList = delete_from_head(testList);
263 assert(getsize(testList) == i);
264 }
265
266 printf("\nTesting inserting at tail:\n");
267 for (int i = 0; i < 5; ++i)
268 {
269 display_list(testList);
270 testList = insert_at_tail(testList, array[i]);
271 assert(get(testList, i) == array[i]);
272 assert(getsize(testList) == i + 1);
273 }
274
275 printf("\nTesting removing from tail:\n");
276 for (int i = 4; i > -1; --i)
277 {
278 display_list(testList);
279 testList = delete_from_tail(testList);
280 assert(getsize(testList) == i);
281 // If list is not empty, assert that accessing the just removed element
282 // will wrap around to the list head
283 if (testList != NULL)
284 {
285 assert(get(testList, i) == testList->value);
286 }
287 else
288 {
289 // If the list is empty, assert that the elements were removed after
290 // the correct number of iterations
291 assert(i == 0);
292 }
293 }
294}
ListNode * delete_from_head(ListNode *head)
Function for deletion of the first node in list.
Definition circular_doubly_linked_list.c:111
void display_list(ListNode *head)
Display list function.
Definition circular_doubly_linked_list.c:191
int getsize(ListNode *head)
The function that will return current size of list.
Definition circular_doubly_linked_list.c:169
ListNode * insert_at_head(ListNode *head, uint64_t data)
Insert a node at start of list.
Definition circular_doubly_linked_list.c:55
ListNode * delete_from_tail(ListNode *head)
Function for deletion of the last node in list.
Definition circular_doubly_linked_list.c:140
uint64_t get(ListNode *list, const int index)
access the list by index
Definition circular_doubly_linked_list.c:223
ListNode * insert_at_tail(ListNode *head, uint64_t data)
Insert a node at end of list.
Definition circular_doubly_linked_list.c:84
Here is the call graph for this function: