/*
============================================================================
Name : week2.c
Author : Haytham
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
// Define the structure for a doubly linked list node
struct Node {
int data;
struct Node *next;
struct Node *prev;
};
// Function to insert a new node at the beginning of the doubly linked list
void insertAtBeginning(struct Node **head_ref, int new_data) {
// 1. Allocate memory for the new node
struct Node
*new_node
= malloc(sizeof(struct Node
));
// 2. Set the data for the new node
new_node->data = new_data;
// 3. Make the new node's next point to the current head
new_node->next = *head_ref;
// 4. Set the previous pointer of the new node to NULL (as it will be the new head)
new_node->prev = NULL;
// 5. Change the previous pointer of the current head (if it exists) to the new node
if (*head_ref != NULL) {
(*head_ref)->prev = new_node;
}
// 6. Move the head pointer to the new node
*head_ref = new_node;
}
// Function to insert a new node at the end of the doubly linked list
void insertAtEnd(struct Node **head_ref, int new_data) {
// 1. Allocate memory for the new node
struct Node
*new_node
= malloc(sizeof(struct Node
));
// 2. Set the data for the new node
new_node->data = new_data;
new_node->next = NULL; // The new node will be the last, so next is NULL
// 3. If the list is empty, make the new node the head
if (*head_ref == NULL) {
new_node->prev = NULL;
*head_ref = new_node;
return;
}
// 4. Traverse to the last node of the list
struct Node *ptr = *head_ref;
while (ptr->next != NULL) {
ptr = ptr->next;
}
// 5. Update the last node's next pointer to the new node
ptr->next = new_node;
// 6. Set the new node's prev pointer to the last node
new_node->prev = ptr;
}
// Function to delete the first node of the doubly linked list
void deleteFirstNode(struct Node **head_ref) {
// 1. Check if the list is empty
if (*head_ref == NULL) {
printf("The list is empty. Nothing to delete.\n"); return;
}
// 2. Store the current head node in a temporary variable
struct Node *ptr = *head_ref;
// 3. Update the head pointer to point to the second node
*head_ref = ptr->next;
// 4. Set the previous pointer of the new head to NULL (if the new head exists)
if (*head_ref != NULL) {
(*head_ref)->prev = NULL;
}
// 5. Free the memory occupied by the old head node
}
// Function to delete the last node of the doubly linked list
void deleteLastNode(struct Node **head_ref) {
// 1. Check if the list is empty
if (*head_ref == NULL) {
printf("The list is empty. Nothing to delete.\n"); return;
}
// 2. Check if the list has only one node
if ((*head_ref)->next == NULL) {
*head_ref = NULL;
return;
}
// 3. Traverse to the last node
struct Node *ptr = *head_ref;
while (ptr->next != NULL) {
ptr = ptr->next;
}
// 4. Update the second-to-last node's next pointer to NULL
ptr->prev->next = NULL;
ptr->prev = NULL;
// 5. Free the memory occupied by the last node
}
// Function to print the doubly linked list
void printList(struct Node *node) {
struct Node *last;
printf("Forward Traversal: "); while (node != NULL) {
last = node;
node = node->next;
}
}
int main() {
// Create an empty doubly linked list
struct Node *head = NULL;
// Insert some nodes at the beginning
insertAtBeginning(&head, 10);
insertAtBeginning(&head, 20);
insertAtBeginning(&head, 30);
// Print the doubly linked list
printList(head);
// Insert some nodes at the end
insertAtEnd(&head, 101);
insertAtEnd(&head, 202);
insertAtEnd(&head, 303);
// Print the doubly linked list
printList(head);
// Delete the first node
deleteFirstNode(&head);
// Delete the last node
deleteLastNode(&head);
// Print the list after deletion
printList(head);
return 0;
}