0% found this document useful (0 votes)
4 views21 pages

Data Structure (Lab) Project

This document outlines a Food Delivery Management System implemented in C++ using various data structures including singly linked lists for customers, doubly linked lists for restaurants, dynamic queues for orders, stacks for completed deliveries, and circular linked lists for delivery riders. Each section includes functionality for adding, displaying, and managing the respective entities. The system is designed to efficiently handle customer registrations, restaurant listings, order processing, delivery tracking, and rider assignments.

Uploaded by

kainaatafzal06
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views21 pages

Data Structure (Lab) Project

This document outlines a Food Delivery Management System implemented in C++ using various data structures including singly linked lists for customers, doubly linked lists for restaurants, dynamic queues for orders, stacks for completed deliveries, and circular linked lists for delivery riders. Each section includes functionality for adding, displaying, and managing the respective entities. The system is designed to efficiently handle customer registrations, restaurant listings, order processing, delivery tracking, and rider assignments.

Uploaded by

kainaatafzal06
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

DATA STRUCTURE (LAB)

PROJECT

SUBMITTED BY : - KAINAAT AFZAL

STUDENT ID : - S2025408067

SUBMITTED TO : - SYEDA NIMRA ZAMIR


// ============================================================
// FOOD DELIVERY MANAGEMENT SYSTEM
// ============================================================

#include <iostream>
#include <cstring>
using namespace std;

// ============================================================
// SECTION 1: SINGLY LINKED LIST — CUSTOMERS
// Each customer has an ID, name, and address.
// New customers are added at the end of the list.
// ============================================================

struct CustomerNode {
int id;
char name[50];
char address[100];
CustomerNode* next;
};

class CustomerList {
private:
CustomerNode* head;
int count;

public:
CustomerList() {
head = NULL;
count = 0;
}

// ADD CUSTOMER (insertion at tail)


void addCustomer(int id, const char* name, const char* address) {
// Create a new node on the heap
CustomerNode* newNode = new CustomerNode;
newNode->id = id;
strcpy(newNode->name, name);
strcpy(newNode->address, address);
newNode->next = NULL;
if (head == NULL) {
head = newNode;
} else {
CustomerNode* temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
count++;
cout << "\n [Customer Added] " << name
<< " (ID: " << id << ")\n";
}

// DISPLAY ALL CUSTOMERS (traversal)


void displayCustomers() {
if (head == NULL) {
cout << "\n No customers registered yet.\n";
return;
}
cout << "\n ===== Customer List (" << count << " total) =====\n";
CustomerNode* temp = head;
int pos = 1;
while (temp != NULL) {
cout << " " << pos << ". ID: " << temp->id
<< " | Name: " << temp->name
<< " | Address: " << temp->address << "\n";
temp = temp->next;
pos++;
}
}

// FIND CUSTOMER BY ID
bool customerExists(int id) {
CustomerNode* temp = head;
while (temp != NULL) {
if (temp->id == id) return true;
temp = temp->next;
}
return false;
}

// Destructor: free all nodes to prevent memory leaks


~CustomerList() {
CustomerNode* temp = head;
while (temp != NULL) {
CustomerNode* toDelete = temp;
temp = temp->next;
delete toDelete;
}
}
};

// ============================================================
// SECTION 2: DOUBLY LINKED LIST — RESTAURANTS
// Each restaurant has an ID and a name.
// The doubly linked list allows traversal in both directions.
// ============================================================

struct RestaurantNode {
int id;
char name[50];
char cuisine[50];
RestaurantNode* prev;
RestaurantNode* next;
};

class RestaurantList {
private:
RestaurantNode* head;
RestaurantNode* tail;
int count;

public:
RestaurantList() {
head = NULL;
tail = NULL;
count = 0;
}
// ADD RESTAURANT (insertion at tail)
void addRestaurant(int id, const char* name, const char* cuisine) {
RestaurantNode* newNode = new RestaurantNode;
newNode->id = id;
strcpy(newNode->name, name);
strcpy(newNode->cuisine, cuisine);
newNode->prev = NULL;
newNode->next = NULL;

if (head == NULL) {
head = newNode;
tail = newNode;
} else {
tail->next = newNode;
newNode->prev = tail;
tail = newNode;
}
count++;
cout << "\n [Restaurant Added] " << name
<< " | Cuisine: " << cuisine
<< " (ID: " << id << ")\n";
}

// DISPLAY RESTAURANTS (forward traversal)


void displayRestaurants() {
if (head == NULL) {
cout << "\n No restaurants registered yet.\n";
return;
}
cout << "\n ===== Restaurant List (" << count << " total) =====\
n";
RestaurantNode* temp = head;
int pos = 1;
while (temp != NULL) {
cout << " " << pos << ". ID: " << temp->id
<< " | Name: " << temp->name
<< " | Cuisine: " << temp->cuisine;
if (temp->prev != NULL)
cout << " | Prev: " << temp->prev->name;
else
cout << " | Prev: ---";
if (temp->next != NULL)
cout << " | Next: " << temp->next->name;
else
cout << " | Next: ---";
cout << "\n";
temp = temp->next;
pos++;
}
}

// CHECK IF RESTAURANT EXISTS


bool restaurantExists(int id) {
RestaurantNode* temp = head;
while (temp != NULL) {
if (temp->id == id) return true;
temp = temp->next;
}
return false;
}

~RestaurantList() {
RestaurantNode* temp = head;
while (temp != NULL) {
RestaurantNode* toDelete = temp;
temp = temp->next;
delete toDelete;
}
}
};

// ============================================================
// SECTION 3: DYNAMIC QUEUE — FOOD ORDERS
// Orders are placed at the REAR and processed from the FRONT.
// This follows FIFO (First In, First Out) principle.
// ============================================================

struct OrderNode {
int orderId;
int customerId;
int restaurantId;
char foodItem[100];
OrderNode* next;
};

class OrderQueue {
private:
OrderNode* front;
OrderNode* rear;
int size;

public:
OrderQueue() {
front = NULL;
rear = NULL;
size = 0;
}

// ENQUEUE — Place a new order


void enqueue(int orderId, int custId, int restId, const char* item) {
OrderNode* newNode = new OrderNode;
newNode->orderId = orderId;
newNode->customerId = custId;
newNode->restaurantId = restId;
strcpy(newNode->foodItem, item);
newNode->next = NULL;

if (rear == NULL) {
front = newNode;
rear = newNode;
} else {
rear->next = newNode;
rear = newNode;
}
size++;
cout << "\n [Order Placed] Order #" << orderId
<< " | Item: " << item
<< " | Customer ID: " << custId
<< " | Restaurant ID: " << restId << "\n";
}

// DEQUEUE — Process the front order


// Returns the processed order node (caller must delete it)
OrderNode* dequeue() {
if (front == NULL) {
cout << "\n No orders in the queue.\n";
return NULL;
}
OrderNode* processed = front;
front = front->next;
if (front == NULL) rear = NULL;
processed->next = NULL;
size--;
cout << "\n [Order Processed] Order #" << processed->orderId
<< " | Item: " << processed->foodItem << "\n";
return processed;
}

// CHECK IF QUEUE IS EMPTY


bool isEmpty() {
return front == NULL;
}

// DISPLAY ALL PENDING ORDERS


void displayOrders() {
if (front == NULL) {
cout << "\n No pending orders in the queue.\n";
return;
}
cout << "\n ===== Pending Orders (" << size << " total) =====\n";
OrderNode* temp = front;
int pos = 1;
while (temp != NULL) {
cout << " " << pos << ". Order #" << temp->orderId
<< " | Item: " << temp->foodItem
<< " | Customer ID: " << temp->customerId
<< " | Restaurant ID: " << temp->restaurantId << "\n";
temp = temp->next;
pos++;
}
}

~OrderQueue() {
OrderNode* temp = front;
while (temp != NULL) {
OrderNode* toDelete = temp;
temp = temp->next;
delete toDelete;
}
}
};

// ============================================================
// SECTION 4: DYNAMIC STACK — COMPLETED DELIVERIES
// Each completed delivery is pushed onto the stack.
// The most recently completed delivery is on TOP.
// This follows LIFO (Last In, First Out) principle.
// ============================================================

struct DeliveryNode {
int orderId;
int customerId;
char foodItem[100];
char riderName[50];
DeliveryNode* next;
};

class DeliveryStack {
private:
DeliveryNode* top;
int size;

public:
DeliveryStack() {
top = NULL;
size = 0;
}
// PUSH — Record a completed delivery
void push(int orderId, int custId, const char* item, const char*
rider) {
DeliveryNode* newNode = new DeliveryNode;
newNode->orderId = orderId;
newNode->customerId = custId;
strcpy(newNode->foodItem, item);
strcpy(newNode->riderName, rider);
newNode->next = top;
top = newNode;
size++;
cout << "\n [Delivery Completed] Order #" << orderId
<< " delivered by " << rider << "\n";
}

// POP — Remove and return the top delivery


void pop() {
if (top == NULL) {
cout << "\n No completed deliveries on record.\n";
return;
}
DeliveryNode* toDelete = top;
cout << "\n [Delivery Removed from Stack] Order #"
<< top->orderId << "\n";
top = top->next;
delete toDelete;
size--;
}

// DISPLAY ALL COMPLETED DELIVERIES


void displayDeliveries() {
if (top == NULL) {
cout << "\n No completed deliveries yet.\n";
return;
}
cout << "\n ===== Completed Deliveries (most recent first) =====\
n";
cout << " Total: " << size << "\n";
DeliveryNode* temp = top;
int pos = 1;
while (temp != NULL) {
cout << " " << pos << ". Order #" << temp->orderId
<< " | Item: " << temp->foodItem
<< " | Customer: " << temp->customerId
<< " | Rider: " << temp->riderName << "\n";
temp = temp->next;
pos++;
}
}

// CHECK IF STACK IS EMPTY


bool isEmpty() {
return top == NULL;
}

// PEEK — View the top delivery without removing


void peek() {
if (top == NULL) {
cout << "\n Stack is empty.\n";
} else {
cout << "\n [Top of Stack] Order #" << top->orderId
<< " | Item: " << top->foodItem
<< " | Rider: " << top->riderName << "\n";
}
}

~DeliveryStack() {
DeliveryNode* temp = top;
while (temp != NULL) {
DeliveryNode* toDelete = temp;
temp = temp->next;
delete toDelete;
}
}
};

// ============================================================
// SECTION 5: CIRCULAR LINKED LIST — DELIVERY RIDERS
// Riders are arranged in a circle.
// When assigning riders we go one by one.
// The last node's 'next' points back to the first node.
// ============================================================

struct RiderNode {
int id;
char name[50];
bool available;
RiderNode* next;
};

class RiderCircularList {
private:
RiderNode* tail;
int count;

public:
RiderCircularList() {
tail = NULL;
count = 0;
}

//ADD RIDER (insertion into circle)


void addRider(int id, const char* name) {
RiderNode* newNode = new RiderNode;
newNode->id = id;
strcpy(newNode->name, name);
newNode->available = true;

if (tail == NULL) {
newNode->next = newNode;
tail = newNode;
} else {
newNode->next = tail->next;
tail->next = newNode;
tail = newNode;
}
count++;
cout << "\n [Rider Added] " << name
<< " (ID: " << id << ")\n";
}
// ASSIGN FIRST AVAILABLE RIDER
// Returns the rider node pointer or NULL if none available
RiderNode* assignRider() {
if (tail == NULL) {
cout << "\n No riders registered.\n";
return NULL;
}

RiderNode* current = tail->next;


int checked = 0;

// Traverse the circle once looking for a free rider


while (checked < count) {
if (current->available) {
current->available = false;
cout << "\n [Rider Assigned] " << current->name
<< " (ID: " << current->id << ")\n";
return current;
}
current = current->next;
checked++;
}

cout << "\n All riders are currently busy.\n";


return NULL;
}

// FREE A RIDER (mark available again)


void freeRider(int riderId) {
if (tail == NULL) return;

RiderNode* current = tail->next;


for (int i = 0; i < count; i++) {
if (current->id == riderId) {
current->available = true;
cout << "\n [Rider Free] " << current->name
<< " is now available.\n";
return;
}
current = current->next;
}
cout << "\n Rider ID " << riderId << " not found.\n";
}

// DISPLAY ALL RIDERS (circular traversal)


void displayRiders() {
if (tail == NULL) {
cout << "\n No riders registered yet.\n";
return;
}
cout << "\n ===== Delivery Riders (" << count << " total) =====\
n";
RiderNode* current = tail->next;
for (int i = 0; i < count; i++) {
cout << " " << (i + 1) << ". ID: " << current->id
<< " | Name: " << current->name
<< " | Status: "
<< (current->available ? "Available" : "On Delivery")
<< "\n";
current = current->next;
}
}

// CHECK IF ANY RIDER IS AVAILABLE


bool anyAvailable() {
if (tail == NULL) return false;
RiderNode* current = tail->next;
for (int i = 0; i < count; i++) {
if (current->available) return true;
current = current->next;
}
return false;
}

// GET RIDER NAME BY ID


void getRiderName(int id, char* buffer) {
if (tail == NULL) { strcpy(buffer, "Unknown"); return; }
RiderNode* current = tail->next;
for (int i = 0; i < count; i++) {
if (current->id == id) {
strcpy(buffer, current->name);
return;
}
current = current->next;
}
strcpy(buffer, "Unknown");
}

~RiderCircularList() {
if (tail == NULL) return;
RiderNode* current = tail->next;
// Break the circle first
tail->next = NULL;
while (current != NULL) {
RiderNode* toDelete = current;
current = current->next;
delete toDelete;
}
}
};

// ============================================================
// SECTION 6: HELPER UTILITIES
// ============================================================

// Print a decorative section separator


void printLine() {
cout << " -----------------------------------------------\n";
}

// Print the main menu


void printMenu() {
cout << "\n ===============================================\n";
cout << " FOOD DELIVERY MANAGEMENT SYSTEM\n";
cout << " ===============================================\n";
cout << " 1. Add Customer\n";
cout << " 2. Display Customers\n";
cout << " 3. Add Restaurant\n";
cout << " 4. Display Restaurants\n";
cout << " 5. Place Order\n";
cout << " 6. Process Order (Dequeue)\n";
cout << " 7. Add Rider\n";
cout << " 8. Assign Rider to Active Order\n";
cout << " 9. Complete Delivery (Push to Stack)\n";
cout << " 10. Display Completed Deliveries\n";
cout << " 11. Exit\n";
cout << " -----------------------------------------------\n";
cout << " Enter your choice: ";
}

// ============================================================
// SECTION 7: MAIN — MENU-DRIVEN PROGRAM
// ============================================================

int main() {

// Instantiate all data structures


CustomerList customers;
RestaurantList restaurants;
OrderQueue orders;
DeliveryStack deliveries;
RiderCircularList riders;

// Counters for auto-incrementing IDs


int customerIdCounter = 1;
int restaurantIdCounter = 1;
int orderIdCounter = 1;
int riderIdCounter = 1;

// Temporarily holds the last processed (dequeued) order


// so it can be completed in the next step
int activeOrderId = -1;
int activeCustomerId = -1;
char activeFoodItem[100] = "";
int activeRiderId = -1;
char activeRiderName[50] = "";
bool orderBeingDelivered = false;

int choice;
cout << "\n Welcome to the Food Delivery Management System!\n";

do {
printMenu();
cin >> choice;
[Link]();

printLine();

// OPTION 1: Add Customer (Singly Linked List)


if (choice == 1) {
char name[50], address[100];
cout << "\n Enter customer name : ";
[Link](name, 50);
cout << " Enter customer address : ";
[Link](address, 100);
[Link](customerIdCounter, name, address);
customerIdCounter++;
}

// OPTION 2: Display Customers


else if (choice == 2) {
[Link]();
}

// OPTION 3: Add Restaurant (Doubly Linked List)


else if (choice == 3) {
char name[50], cuisine[50];
cout << "\n Enter restaurant name : ";
[Link](name, 50);
cout << " Enter cuisine type : ";
[Link](cuisine, 50);
[Link](restaurantIdCounter, name, cuisine);
restaurantIdCounter++;
}

// OPTION 4: Display Restaurants


else if (choice == 4) {
[Link]();
}

// OPTION 5: Place Order (Enqueue)


else if (choice == 5) {
int custId, restId;
char item[100];
cout << "\n Enter customer ID : ";
cin >> custId;
[Link]();

if (![Link](custId)) {
cout << "\n Customer ID " << custId << " not found.
Please add the customer first.\n";
} else {
cout << " Enter restaurant ID : ";
cin >> restId;
[Link]();

if (![Link](restId)) {
cout << "\n Restaurant ID " << restId << " not found.
Please add the restaurant first.\n";
} else {
cout << " Enter food item : ";
[Link](item, 100);
[Link](orderIdCounter, custId, restId, item);
orderIdCounter++;
}
}
}

// OPTION 6: Process Order (Dequeue from Queue)


else if (choice == 6) {
if ([Link]()) {
cout << "\n No orders to process.\n";
} else if (orderBeingDelivered) {
cout << "\n An order is already being delivered.\n";
cout << " Complete the current delivery first (Option
9).\n";
} else {
OrderNode* processed = [Link]();
if (processed != NULL) {

// Save this order as the active delivery


activeOrderId = processed->orderId;
activeCustomerId = processed->customerId;
strcpy(activeFoodItem, processed->foodItem);
activeRiderId = -1;
orderBeingDelivered = true;
delete processed;
cout << " Order #" << activeOrderId
<< " is ready. Assign a rider (Option 8).\n";
}
}
}

// OPTION 7: Add Rider (Circular Linked List)


else if (choice == 7) {
char name[50];
cout << "\n Enter rider name : ";
[Link](name, 50);
[Link](riderIdCounter, name);
riderIdCounter++;
}

// OPTION 8: Assign Rider to Active Order


else if (choice == 8) {
if (!orderBeingDelivered) {
cout << "\n No active order to assign a rider to.\n";
cout << " Process an order first (Option 6).\n";
} else if (activeRiderId != -1) {
cout << "\n Rider already assigned to Order #"
<< activeOrderId << ".\n";
} else {
[Link]();
RiderNode* rider = [Link]();
if (rider != NULL) {
activeRiderId = rider->id;
strcpy(activeRiderName, rider->name);
cout << " Rider " << activeRiderName
<< " assigned to Order #" << activeOrderId << ".\
n";
}
}
}

// OPTION 9: Complete Delivery (Push onto Stack)


else if (choice == 9) {
if (!orderBeingDelivered) {
cout << "\n No active delivery to complete.\n";
} else if (activeRiderId == -1) {
cout << "\n Please assign a rider first (Option 8).\n";
} else {

// Push the completed delivery onto the stack


[Link](activeOrderId, activeCustomerId,
activeFoodItem, activeRiderName);

// Free the rider so they can take new orders


[Link](activeRiderId);

// Reset the active order state


activeOrderId = -1;
activeCustomerId = -1;
activeFoodItem[0] = '\0';
activeRiderId = -1;
activeRiderName[0] = '\0';
orderBeingDelivered = false;
}
}

// OPTION 10: Display Completed Deliveries (Stack)


else if (choice == 10) {
[Link]();
}

// OPTION 11: Exit


else if (choice == 11) {
cout << "\n Thank you for using the Food Delivery System!\n";
cout << " Goodbye!\n\n";
}
else {
cout << "\n Invalid choice. Please enter a number between 1
and 11.\n";
}

printLine();

} while (choice != 11);

// All destructors run automatically here, freeing heap memory.


}

You might also like