Below is a C program that implements basic operations for both singly and doubly linked lists. The operations include creating a list, inserting nodes at the beginning, end, and a specified position, as well as deleting nodes from the beginning, end, and a specified position.
C Program for Singly Linked List and Doubly Linked List Operations
#include <stdio.h>
#include <stdlib.h>
// Singly Linked List Node Definition
typedef struct SinglyNode {
int data;
struct SinglyNode* next;
} SinglyNode;
// Doubly Linked List Node Definition
typedef struct DoublyNode {
int data;
struct DoublyNode* next;
struct DoublyNode* prev;
} DoublyNode;
// Function Prototypes for Singly Linked List
SinglyNode* createSinglyNode(int value);
void insertAtBeginningSingly(SinglyNode** head, int value);
void insertAtEndSingly(SinglyNode** head, int value);
void insertAtPositionSingly(SinglyNode** head, int value, int position);
void deleteFromBeginningSingly(SinglyNode** head);
void deleteFromEndSingly(SinglyNode** head);
void deleteAtPositionSingly(SinglyNode** head, int position);
void displaySingly(SinglyNode* head);
// Function Prototypes for Doubly Linked List
DoublyNode* createDoublyNode(int value);
void insertAtBeginningDoubly(DoublyNode** head, int value);
void insertAtEndDoubly(DoublyNode** head, int value);
void insertAtPositionDoubly(DoublyNode** head, int value, int position);
void deleteFromBeginningDoubly(DoublyNode** head);
void deleteFromEndDoubly(DoublyNode** head);
void deleteAtPositionDoubly(DoublyNode** head, int position);
void displayDoubly(DoublyNode* head);
int main() {
SinglyNode* singlyHead = NULL;
DoublyNode* doublyHead = NULL;
// Singly Linked List Operations
printf(“Singly Linked List Operations:\n”);
insertAtEndSingly(&singlyHead, 10);
insertAtEndSingly(&singlyHead, 20);
insertAtBeginningSingly(&singlyHead, 5);
insertAtPositionSingly(&singlyHead, 15, 2);
displaySingly(singlyHead);
deleteFromBeginningSingly(&singlyHead);
displaySingly(singlyHead);
deleteFromEndSingly(&singlyHead);
displaySingly(singlyHead);
deleteAtPositionSingly(&singlyHead, 1);
displaySingly(singlyHead);
// Doubly Linked List Operations
printf(“\nDoubly Linked List Operations:\n”);
insertAtEndDoubly(&doublyHead, 100);
insertAtEndDoubly(&doublyHead, 200);
insertAtBeginningDoubly(&doublyHead, 50);
insertAtPositionDoubly(&doublyHead, 150, 2);
displayDoubly(doublyHead);
deleteFromBeginningDoubly(&doublyHead);
displayDoubly(doublyHead);
deleteFromEndDoubly(&doublyHead);
displayDoubly(doublyHead);
deleteAtPositionDoubly(&doublyHead, 1);
displayDoubly(doublyHead);
return 0;
}
// Singly Linked List Functions
SinglyNode* createSinglyNode(int value) {
SinglyNode* newNode = (SinglyNode*)malloc(sizeof(SinglyNode));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
void insertAtBeginningSingly(SinglyNode** head, int value) {
SinglyNode* newNode = createSinglyNode(value);
newNode->next = *head;
*head = newNode;
}
void insertAtEndSingly(SinglyNode** head, int value) {
SinglyNode* newNode = createSinglyNode(value);
if (*head == NULL) {
*head = newNode;
return;
}
SinglyNode* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
void insertAtPositionSingly(SinglyNode** head, int value, int position) {
SinglyNode* newNode = createSinglyNode(value);
if (position == 0) {
insertAtBeginningSingly(head, value);
return;
}
SinglyNode* temp = *head;
for (int i = 0; temp != NULL && i < position – 1; i++) {
temp = temp->next;
}
if (temp == NULL) {
printf(“Position is out of bounds.\n”);
return;
}
newNode->next = temp->next;
temp->next = newNode;
}
void deleteFromBeginningSingly(SinglyNode** head) {
if (*head == NULL) return; // List is empty
SinglyNode* temp = *head;
*head = (*head)->next;
free(temp);
}
void deleteFromEndSingly(SinglyNode** head) {
if (*head == NULL) return; // List is empty
SinglyNode* temp = *head;
if (temp->next == NULL) {
free(temp);
*head = NULL;
return;
}
while (temp->next->next != NULL) {
temp = temp->next;
}
free(temp->next);
temp->next = NULL;
}
void deleteAtPositionSingly(SinglyNode** head, int position) {
if (*head == NULL) return; // List is empty
SinglyNode* temp = *head;
if (position == 0) {
deleteFromBeginningSingly(head);
return;
}
for (int i = 0; temp != NULL && i < position – 1; i++) {
temp = temp->next;
}
if (temp == NULL || temp->next == NULL) {
printf(“Position is out of bounds.\n”);
return;
}
SinglyNode* nextNode = temp->next->next;
free(temp->next);
temp->next = nextNode;
}
void displaySingly(SinglyNode* head) {
if (head == NULL) {
printf(“Singly Linked List is empty.\n”);
return;
}
SinglyNode* temp = head;
printf(“Singly Linked List: “);
while (temp != NULL) {
printf(“%d -> “, temp->data);
temp = temp->next;
}
printf(“NULL\n”);
}
// Doubly Linked List Functions
DoublyNode* createDoublyNode(int value) {
DoublyNode* newNode = (DoublyNode*)malloc(sizeof(DoublyNode));
newNode->data = value;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}
void insertAtBeginningDoubly(DoublyNode** head, int value) {
DoublyNode* newNode = createDoublyNode(value);
newNode->next = *head;
newNode->prev = NULL;
if (*head != NULL) {
(*head)->prev = newNode;
}
*head = newNode;
}
void insertAtEndDoubly(DoublyNode** head, int value) {
DoublyNode* newNode = createDoublyNode(value);
if (*head == NULL) {
*head = newNode;
return;
}
DoublyNode* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
newNode->prev = temp;
}
void insertAtPositionDoubly(DoublyNode** head, int value, int position) {
DoublyNode* newNode = createDoublyNode(value);
if (position == 0) {
insertAtBeginningDoubly(head, value);
return;
}
DoublyNode* temp = *head;
for (int i = 0; temp != NULL && i < position – 1; i++) {
temp = temp->next;
}
if (temp == NULL) {
printf(“Position is out of bounds.\n”);
return;
}
newNode->next = temp->next;
newNode->prev = temp;
if (temp->next != NULL) {
temp->next->prev = newNode;
}
temp->next = newNode;
}
void deleteFromBeginningDoubly(DoublyNode** head) {
if (*head == NULL) return; // List is empty
DoublyNode* temp = *head;
*head = (*head)->next;
if (*head != NULL) {
(*head)->prev = NULL;
}
free(temp);
}
void deleteFromEndDoubly(DoublyNode** head) {
if (*head == NULL) return; // List is empty
DoublyNode* temp = *head;
if (temp->next == NULL) {
free(temp);
*head = NULL;
return;
}
while (temp->next != NULL) {
temp = temp->next;
 Write a program to implement stack and queue as linked list.
Here’s a C program that implements both stack and queue using linked lists. The stack follows the Last In, First Out (LIFO) principle, while the queue follows the First In, First Out (FIFO) principle.
C Program to Implement Stack and Queue as Linked List
#include <stdio.h>
#include <stdlib.h>
// Stack Node Definition
typedef struct StackNode {
int data;
struct StackNode* next;
} StackNode;
// Queue Node Definition
typedef struct QueueNode {
int data;
struct QueueNode* next;
} QueueNode;
// Stack Functions
StackNode* createStackNode(int value);
void push(StackNode** top, int value);
int pop(StackNode** top);
int peek(StackNode* top);
int isStackEmpty(StackNode* top);
void displayStack(StackNode* top);
// Queue Functions
QueueNode* createQueueNode(int value);
void enqueue(QueueNode** front, QueueNode** rear, int value);
int dequeue(QueueNode** front);
int peekQueue(QueueNode* front);
int isQueueEmpty(QueueNode* front);
void displayQueue(QueueNode* front);
int main() {
// Stack Operations
StackNode* stackTop = NULL;
printf(“Stack Operations:\n”);
push(&stackTop, 10);
push(&stackTop, 20);
push(&stackTop, 30);
displayStack(stackTop);
printf(“Popped: %d\n”, pop(&stackTop));
displayStack(stackTop);
printf(“Top element: %d\n”, peek(stackTop));
// Queue Operations
QueueNode* queueFront = NULL;
QueueNode* queueRear = NULL;
printf(“\nQueue Operations:\n”);
enqueue(&queueFront, &queueRear, 100);
enqueue(&queueFront, &queueRear, 200);
enqueue(&queueFront, &queueRear, 300);
displayQueue(queueFront);
printf(“Dequeued: %d\n”, dequeue(&queueFront));
displayQueue(queueFront);
printf(“Front element: %d\n”, peekQueue(queueFront));
return 0;
}
// Stack Functions Implementation
StackNode* createStackNode(int value) {
StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
void push(StackNode** top, int value) {
StackNode* newNode = createStackNode(value);
newNode->next = *top;
*top = newNode;
}
int pop(StackNode** top) {
if (isStackEmpty(*top)) {
printf(“Stack Underflow\n”);
return -1; // Indicates that the stack is empty
}
StackNode* temp = *top;
int poppedValue = temp->data;
*top = (*top)->next;
free(temp);
return poppedValue;
}
int peek(StackNode* top) {
if (isStackEmpty(top)) {
printf(“Stack is empty\n”);
return -1; // Indicates that the stack is empty
}
return top->data;
}
int isStackEmpty(StackNode* top) {
return top == NULL;
}
void displayStack(StackNode* top) {
if (isStackEmpty(top)) {
printf(“Stack is empty\n”);
return;
}
StackNode* temp = top;
printf(“Stack: “);
while (temp != NULL) {
printf(“%d -> “, temp->data);
temp = temp->next;
}
printf(“NULL\n”);
}
// Queue Functions Implementation
QueueNode* createQueueNode(int value) {
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
void enqueue(QueueNode** front, QueueNode** rear, int value) {
QueueNode* newNode = createQueueNode(value);
if (*rear == NULL) {
*front = *rear = newNode;
return;
}
(*rear)->next = newNode;
*rear = newNode;
}
int dequeue(QueueNode** front) {
if (isQueueEmpty(*front)) {
printf(“Queue Underflow\n”);
return -1; // Indicates that the queue is empty
}
QueueNode* temp = *front;
int dequeuedValue = temp->data;
*front = (*front)->next;
if (*front == NULL) {
// If the queue becomes empty
printf(“Queue is now empty\n”);
}
free(temp);
return dequeuedValue;
}
int peekQueue(QueueNode* front) {
if (isQueueEmpty(front)) {
printf(“Queue is empty\n”);
return -1; // Indicates that the queue is empty
}
return front->data;
}
int isQueueEmpty(QueueNode* front) {
return front == NULL;
}
void displayQueue(QueueNode* front) {
if (isQueueEmpty(front)) {
printf(“Queue is empty\n”);
return;
}
QueueNode* temp = front;
printf(“Queue: “);
while (temp != NULL) {
printf(“%d -> “, temp->data);
temp = temp->next;
}
printf(“NULL\n”);
}
Explanation of the Program
- Data Structures:
- StackNode: Structure to represent a node in the stack.
- QueueNode: Structure to represent a node in the queue.
- Stack Operations:
- createStackNode: Allocates memory for a new stack node.
- push: Inserts a new node at the top of the stack.
- pop: Removes and returns the top node from the stack.
- peek: Returns the data of the top node without removing it.
- isStackEmpty: Checks if the stack is empty.
- displayStack: Displays all elements in the stack.
- Queue Operations:
- createQueueNode: Allocates memory for a new queue node.
- enqueue: Inserts a new node at the end of the queue.
- dequeue: Removes and returns the front node from the queue.
- peekQueue: Returns the data of the front node without removing it.
- isQueueEmpty: Checks if the queue is empty.
- displayQueue: Displays all elements in the queue.
Output Example
When you run the program, you will see output similar to this:
Stack Operations:
Stack: 30 -> 20 -> 10 -> NULL
Popped: 30
Stack: 20 -> 10 -> NULL
Top element: 20
Queue Operations:
Queue: 100 -> 200 -> 300 -> NULL
Dequeued: 100
Queue: 200 -> 300 -> NULL
Front element: 200