Reputation: 21
I made a Doubly Linked List, but instead of manually assigning the values (10, 20, 30) I want to make a for
loop and put the data that way to make it efficient.
I did it in Singly Linked List but the same is not happening over here and only backward_traversing
function works.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int value;
struct Node *next_link;
struct Node *prev_link;
} Node;
Node *create_node(int value)
{
Node *new_node = malloc(sizeof(Node));
new_node->value = value;
new_node->next_link = NULL;
new_node->prev_link = NULL;
return new_node;
}
void forward_traversing(Node *head)
{
Node *temp = head;
while (temp != NULL)
{
printf("%d ", temp -> value);
temp = temp->next_link;
}
printf("\n");
}
void backward_traversing(Node *tail)
{
Node *temp = tail;
while (temp != NULL)
{
printf("%d ", temp->value);
temp = temp->prev_link;
}
printf("\n");
}
void show_first(Node *head)
{
printf("%d \n", head->value);
}
void show_last(Node *tail)
{
printf("%d \n", tail->value);
}
int main()
{
Node *head, *temp, *tail;
for (int i = 0; i <= 25; i++){
temp = create_node(i);
temp -> next_link = head;
head = temp;
}
forward_traversing(head);
backward_traversing(tail);
show_first(head);
show_last(tail);
return 0;
}
Upvotes: 1
Views: 124
Reputation: 17503
It is useful to define a type to hold the head and tail pointers of the list since some functions may need to update both the head and tail pointers.
Fundamental operations include:
Functions can be written to perform those operations, as in the following example based on OP's original code (OP's functions that that took a head pointer or a tail pointer have been changed to take a pointer to the list control structure):
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int value;
struct Node *next_link;
struct Node *prev_link;
} Node;
typedef struct List
{
struct Node *head;
struct Node *tail;
} List;
Node *create_node(int value)
{
Node *new_node = malloc(sizeof(Node));
new_node->value = value;
new_node->next_link = NULL;
new_node->prev_link = NULL;
return new_node;
}
Node *node_next(Node *node)
{
return node ? node->next_link : NULL;
}
Node *node_prev(Node *node)
{
return node ? node->prev_link : NULL;
}
void free_node(Node *node)
{
free(node);
}
void list_init(List *list)
{
list->head = NULL;
list->tail = NULL;
}
Node *list_first(List *list)
{
return list->head;
}
Node *list_last(List *list)
{
return list->tail;
}
/* Note: existingnode assumed to be on the list if non-null */
/* Note: if existingnode is null, newnode will be prepended to the list */
void list_insert_before(List *list, Node * restrict existingnode,
Node * restrict newnode)
{
if (newnode)
{
Node *prev;
if (existingnode == NULL)
{
/* newnode will be prepended before head (if it exists) */
existingnode = list->head;
}
if (existingnode)
{
prev = existingnode->prev_link;
existingnode->prev_link = newnode;
}
else
{
/* list is empty */
prev = NULL;
list->tail = newnode;
}
newnode->prev_link = prev;
newnode->next_link = existingnode;
if (prev)
{
prev->next_link = newnode;
}
else
{
/* newnode being prepended to the list */
list->head = newnode;
}
}
}
void list_prepend(List *list, Node *node)
{
/* Note: list->head may be null */
list_insert_before(list, list->head, node);
}
void list_append(List *list, Node *node)
{
if (node)
{
node->next_link = NULL;
node->prev_link = list->tail;
if (list->tail)
{
list->tail->next_link = node;
}
else
{
/* list is empty */
list->head = node;
}
list->tail = node;
}
}
/* Note: existingnode assumed to be on the list if non-null */
/* Note: if existingnode is null, newnode will be appended to the list */
void list_insert_after(List *list, Node * restrict existingnode,
Node * restrict newnode)
{
if (existingnode == NULL || existingnode == list->tail)
{
list_append(list, newnode);
}
else
{
list_insert_before(list, existingnode->next_link, newnode);
}
}
/* Note: node assumed to be on the list if non-null */
void list_remove_node(List *list, Node *node)
{
if (node)
{
Node *next = node->next_link;
Node *prev = node->prev_link;
if (next)
{
next->prev_link = prev;
}
else
{
list->tail = prev;
}
if (prev)
{
prev->next_link = next;
}
else
{
list->head = next;
}
node->next_link = NULL;
node->prev_link = NULL;
}
}
Node *list_remove_first(List *list)
{
Node *node = list_first(list);
list_remove_node(list, node);
return node;
}
Node *list_remove_last(List *list)
{
Node *node = list_last(list);
list_remove_node(list, node);
return node;
}
void free_list_nodes(List *list)
{
Node *temp;
while ((temp = list_remove_first(list)) != NULL)
{
free_node(temp);
}
}
void forward_traversing(List *list)
{
Node *temp = list_first(list);
while (temp != NULL)
{
printf("%d ", temp->value);
temp = temp->next_link;
}
printf("\n");
}
void backward_traversing(List *list)
{
Node *temp = list_last(list);
while (temp != NULL)
{
printf("%d ", temp->value);
temp = temp->prev_link;
}
printf("\n");
}
void show_first(List *list)
{
Node *head = list_first(list);
if (head)
{
printf("%d \n", head->value);
}
else
{
printf("(empty)\n");
}
}
void show_last(List *list)
{
Node *tail = list_last(list);
if (tail)
{
printf("%d \n", tail->value);
}
else
{
printf("(empty)\n");
}
}
int main()
{
List list;
Node *node;
int i;
list_init(&list);
for (i = 10; i < 50; i += 10)
{
node = create_node(i);
if (node)
{
list_append(&list, node);
}
}
printf("Initial list\n");
forward_traversing(&list);
backward_traversing(&list);
printf("Remove first node\n");
node = list_remove_first(&list); /* (10), 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Prepend removed node to start of list\n");
list_prepend(&list, node); /* 10, 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Remove last node\n");
node = list_remove_last(&list); /* 10, 20, 30, (40) */
forward_traversing(&list);
backward_traversing(&list);
printf("Append removed node to end of list\n");
list_append(&list, node); /* 10, 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Remove third node\n");
node = node_next(node_next(list_first(&list))); /* (30) */
list_remove_node(&list, node); /* 10, 20, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Insert removed node after second node\n");
list_insert_after(&list, node_next(list_first(&list)), node);
/* 10, 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Remove previous (third) node again\n");
list_remove_node(&list, node); /* 10, 20, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("Insert removed node before third (original fourth) node\n");
list_insert_before(&list, node_next(node_next(list_first(&list))),
node); /* 10, 20, 30, 40 */
forward_traversing(&list);
backward_traversing(&list);
printf("First node\n");
show_first(&list);
printf("Last node\n");
show_last(&list);
free_list_nodes(&list);
return 0;
}
Output:
Initial list
10 20 30 40
40 30 20 10
Remove first node
20 30 40
40 30 20
Prepend removed node to start of list
10 20 30 40
40 30 20 10
Remove last node
10 20 30
30 20 10
Append removed node to end of list
10 20 30 40
40 30 20 10
Remove third node
10 20 40
40 20 10
Insert removed node after second node
10 20 30 40
40 30 20 10
Remove previous (third) node again
10 20 40
40 20 10
Insert removed node before third (original fourth) node
10 20 30 40
40 30 20 10
First node
10
Last node
40
Upvotes: 0