-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdata-structures-2024.c
636 lines (562 loc) · 21.5 KB
/
data-structures-2024.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
// #####################################################################################################
// #####################################################################################################
// _____ _______ _____ _______ _____ _ _ _____ _______ _ _ _____ ______ _____
// | __ \ /\|__ __|/\ / ____|__ __| __ \| | | |/ ____|__ __| | | | __ \| ____|/ ____|
// | | | | / \ | | / \ | (___ | | | |__) | | | | | | | | | | | |__) | |__ | (___
// | | | |/ /\ \ | | / /\ \ \___ \ | | | _ /| | | | | | | | | | | _ /| __| \___ \
// | |__| / ____ \| |/ ____ \ ____) | | | | | \ \| |__| | |____ | | | |__| | | \ \| |____ ____) |
// |_____/_/ \_\_/_/ \_\ |_____/ |_| |_| \_\\____/ \_____| |_| \____/|_| \_\______|_____/
// #####################################################################################################
// Data Structures assignment
// University of Pireaus
// April 2024
//
// #####################################################################################################
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Function to clear the screen
// ok on linux/online compilers
// on clion windows it requires to edit projects configuration: Emulate terminal in the output console [X]
void clearScreen(){
#if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
system("clear");
#endif
#if defined(_WIN32) || defined(_WIN64)
system("cls");
#endif
}
void clearInputBuffer() {
printf("\nPress Enter to continue...");
while (getchar() != '\n'); // Clear input buffer
getchar(); // Wait for Enter key
}
// ####################################################################################
// ############################## EXERCISE 1 START ####################################
// ############************************************************************############
// Function to retrieve the value at a given index from a matrix
float retrieve(float *matrix, int index) {
return matrix[index];
}
// Function to update the value at a given index in a matrix
void update(float *matrix, int index, float value) {
matrix[index] = value;
}
// Function to add two matrices B and C and store the result in matrix a
void add_matrices(float *B, float *C, float *a, int size) {
for (int i = 0; i < size; i++) {
a[i] = B[i] + C[i];
}
}
// Function to demonstrate matrix operations
void matrix_operations() {
// Assuming B, C, and a are arrays containing real numbers
float B[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
float C[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
float a[10];
// Retrieve values from B and C matrices
float B_val = retrieve(B, 5); // Get value from matrix B at index 5
float C_val = retrieve(C, 5); // Get value from matrix C at index 5
printf("Values retrieved from matrices B and C: %.2f %.2f\n", B_val, C_val);
// Update values in matrices B and C
update(B, 5, 20); // Update value in matrix B at index 5
update(C, 5, 30); // Update value in matrix C at index 5
printf("Updated matrices B and C:\n");
for (int i = 0; i < 10; i++) {
printf("%.2f ", B[i]);
}
printf("\n");
for (int i = 0; i < 10; i++) {
printf("%.2f ", C[i]);
}
printf("\n");
// Add matrices B and C to obtain matrix a
add_matrices(B, C, a, 10);
printf("Resultant matrix a:\n");
for (int i = 0; i < 10; i++) {
printf("%.2f ", a[i]);
}
printf("\n");
}
// ############************************************************************############
// ############################### EXERCISE 1 END #####################################
// ####################################################################################
// ####################################################################################
// ############################## EXERCISE 2 START ####################################
// ############************************************************************############
// ############************************************************************############
// ############################### EXERCISE 2 END #####################################
// ####################################################################################
// ####################################################################################
// ############################### EXERCISE 3 START ###################################
// ############************************************************************############
// to do:
// - Test changing scanf() with fgets(), to properly handle spaces in user input
// - Find out how to input space " " characters (i.e. name, address)
// - Fix code for VScode erros with buffer overflow on addCourse addStudent
struct studentCourseLink {
struct student *student;
struct studentCourseLink *next;
};
struct course {
char courseName[30];
struct course *next;
struct studentCourseLink *studentsHead; // New field
};
struct student {
int am;
char firstName[30];
char lastName[30];
char patronym[30];
char matronym[30];
char address[30];
int phoneNumber;
int mobileNumber;
struct student *next;
struct course *enrolledCourse; // Directly link to the single course
};
struct student *head;
struct course* courseHead = NULL;
// ############################## COURSE MANAGEMENT - START ################################
struct course* createCourse(const char *courseName) {
struct course* newCourse = (struct course*) malloc(sizeof(struct course));
strcpy(newCourse->courseName, courseName);
newCourse->next = NULL;
newCourse->studentsHead = NULL; // Initialize the list of students enrolled in the course
return newCourse;
}
struct course* findOrCreateCourse(const char *courseName) {
struct course* currentCourse = courseHead; // Assume courseHead is a global pointer to the first course
struct course* lastCourse = NULL;
while (currentCourse != NULL) {
if (strcmp(currentCourse->courseName, courseName) == 0) {
return currentCourse;
}
lastCourse = currentCourse;
currentCourse = currentCourse->next;
}
// Course not found, create new
struct course* newCourse = createCourse(courseName);
if (lastCourse != NULL) {
lastCourse->next = newCourse;
} else {
courseHead = newCourse; // Set as head if first course
}
return newCourse;
}
void addCourse(struct student* student, const char *courseName) {
struct course* course = findOrCreateCourse(courseName);
student->enrolledCourse = course; // Directly link student to this course
}
// ############################## COURSE MANAGEMENT - END ################################
// ############################# STUDENT MANAGEMENT - START ###############################
void addStudent(int am, const char *firstName, const char *lastName, const char *patronym, const char *matronym, const char *address, int phoneNumber, int mobileNumber, const char *courseName) {
struct student *pts;
pts = (struct student*) malloc(sizeof(struct student));
if (pts == NULL) {
// Handle memory allocation failure
printf("Memory allocation failed\n");
return;
}
pts->am = am;
strcpy(pts->firstName, firstName);
strcpy(pts->lastName, lastName);
strcpy(pts->patronym, patronym);
strcpy(pts->matronym, matronym);
strcpy(pts->address, address);
pts->phoneNumber = phoneNumber;
pts->mobileNumber = mobileNumber;
pts->enrolledCourse = NULL; // Initialize the enrolledCourse pointer to NULL
// Now add the course to the student
// This will set the enrolledCourse pointer to the appropriate course
addCourse(pts, courseName);
if(head == NULL){
pts->next = NULL;
head = pts;
} else{
pts->next = head;
head = pts;
}
}
void displayAllStudents() {
clearScreen();
struct student *temp = head;
printf("Student directory:\n");
if (temp == NULL) {
printf("List is empty...\n");
clearInputBuffer();
return;
}
while (temp != NULL) {
printf("Student: AM: %d, Name: %s %s, Patronym: %s, Matronym: %s, Address: %s, Phone Number: %d, Mobile Number: %d, Course: %s\n",
temp->am, temp->firstName, temp->lastName, temp->patronym, temp->matronym, temp->address, temp->phoneNumber, temp->mobileNumber,
temp->enrolledCourse ? temp->enrolledCourse->courseName : "Not enrolled in any course");
temp = temp->next;
}
clearInputBuffer();
}
void displayStudentsByCourse() {
clearScreen();
printf("UNIPI - Data Structures 23-24\n");
char courseName[30];
printf("Enter course name to display students: ");
scanf("%s", courseName);
//scanf("%29s", courseName); // Suggestion to use %29s to prevent buffer overflow
int found = 0;
struct student *temp = head;
printf("Students enrolled in course %s:\n", courseName);
while (temp != NULL) {
if (temp->enrolledCourse != NULL && strcmp(temp->enrolledCourse->courseName, courseName) == 0) {
printf("StudentID: %d, Name: %s %s, Patronym: %s, Matronym: %s, Address: %s, Phone Number: %d, Mobile Number: %d\n",
temp->am, temp->firstName, temp->lastName, temp->patronym, temp->matronym, temp->address, temp->phoneNumber, temp->mobileNumber);
found = 1;
}
temp = temp->next;
}
if (!found) {
printf("No students found for course: %s\n", courseName);
}
clearInputBuffer();
}
void handleaddStudent() {
clearScreen();
int am, phoneNumber, mobileNumber;
char firstName[30], lastName[30], patronym[30], matronym[30], address[30], courseName[30];
printf("UNIPI - Data Structures 23-24\n");
printf("Add student data below:\n");
printf("Enter am: ");
scanf("%d", &am);
printf("Enter first name: ");
scanf("%s", firstName);
printf("Enter last name: ");
scanf("%s", lastName);
printf("Enter patronym: ");
scanf("%s", patronym);
printf("Enter matronym: ");
scanf("%s", matronym);
printf("Enter address: ");
scanf("%s", address);
printf("Enter phone number: ");
scanf("%d", &phoneNumber);
printf("Enter mobile number: ");
scanf("%d", &mobileNumber);
printf("Enter course name: ");
scanf("%s", courseName);
addStudent(am, firstName, lastName, patronym, matronym, address, phoneNumber, mobileNumber, courseName);
}
void studentExamplePreloader() {
// Import sample students for exercise 3 - START
addStudent(1, "Diogenis", "Papadopoulos", "Marios", "Maria", "Aristotelous25", 21012344, 69696969, "data");
addStudent(2, "Ioannis", "Efstratiou", "Kostas", "Kaiti", "panormou1", 24101223, 69696969, "math");
addStudent(3, "Orestis", "Giannou", "Marios", "Maria", "epaminonda", 21012344, 69696969, "data");
addStudent(4, "Nopi", "Afroxilanthou", "Takis", "Efterpi", "kekropos2", 241012323, 69696969, "math");
addStudent(5, "Ian", "Afroxilanthou", "Sakis", "Jane", "anaximandrou5", 241012323, 69696969, "physics");
addStudent(6, "Sandra", "Panagiotou", "Lakis", "Mary", "kekropos2", 241012323, 69696969, "network");
addStudent(7, "Ifigenia", "Yates", "John", "Emily", "kekropos2", 241012323, 69696969, "network");
addStudent(8, "Stavros", "Yates", "Jack", "Emily", "kekropos2", 241012323, 69696969, "network");
printf("Student directory sample is loaded.\n");
clearInputBuffer();
// Import sample students for exercise 3 - END
}
// ############################ STUDENT MANAGEMENT - END ##############################
// ############************************************************************############
// ############################### EXERCISE 3 END #####################################
// ####################################################################################
// ####################################################################################
// ############################## EXERCISE 4 START ####################################
// ############************************************************************############
#define MAX 10 // for exerise 4
void push(int stack[], int *top, int value) {
if (*top < MAX) {
*top = *top + 1;
stack[*top] = value;
printf("%d pushed to stack\n", value);
} else {
printf("The stack is full\n");
exit(EXIT_FAILURE);
}
}
int pop(int stack[], int *top) {
if (*top >= 0) {
int value = stack[*top];
*top = *top - 1;
return value;
} else {
printf("The stack is empty\n");
exit(EXIT_FAILURE);
}
}
void performLIFOStackOperations() {
int stack[MAX];
int top = -1;
int num;
printf("Enter numbers to push onto the stack (enter -1 to stop):\n");
do {
printf("Enter number: ");
scanf("%d", &num);
if (num != -1)
push(stack, &top, num);
} while (num != -1);
if (top >= 0) {
int value = pop(stack, &top);
printf("Popped value: %d\n", value);
} else {
printf("The stack is empty\n");
}
}
// ############************************************************************############
// ############################### EXERCISE 4 END #####################################
// ####################################################################################
// ####################################################################################
// ############################## EXERCISE 5 START ####################################
// ############************************************************************############
typedef struct Node {
int data;
struct Node* next;
} Node;
Node* newNode(int data) {
Node* new_node = (Node*)malloc(sizeof(Node));
if (new_node == NULL) {
printf("Failed to allocate memory\n");
exit(EXIT_FAILURE);
}
new_node->data = data;
new_node->next = NULL;
return new_node;
}
void pushNode(Node** top_ref, int new_data) {
Node* new_node = newNode(new_data);
new_node->next = *top_ref;
*top_ref = new_node;
//printf("%d pushed to stack\n", new_data);
}
int popNode(Node** top_ref) {
if (*top_ref == NULL) {
printf("The stack is empty\n");
exit(EXIT_FAILURE);
}
Node* temp = *top_ref;
*top_ref = (*top_ref)->next;
int popped = temp->data;
free(temp);
return popped;
}
void performLIFOlinkedStackOperations() {
Node* top = NULL;
int data;
printf("Enter numbers to push onto the stack (enter -1 to stop): \n");
while (1) {
printf("Enter number: ");
scanf("%d", &data);
if (data == -1) break; // Stop if the user enters -1
pushNode(&top, data);
}
printf("Popping all elements from the stack:\n");
while (top != NULL) {
printf("%d ", popNode(&top));
}
}
// ############************************************************************############
// ############################### EXERCISE 5 END #####################################
// ####################################################################################
// ####################################################################################
// ############################## EXERCISE 6 START ####################################
// ############************************************************************############
// Function to evaluate the expression [(10+2) x (8-3)] + 2
typedef struct {
int *data;
int top;
int capacity;
} Stack;
// Stack initialization
Stack* createStack(int capacity) {
Stack *stack = (Stack *)malloc(sizeof(Stack));
if (stack == NULL) {
printf("Memory allocation failed\n");
exit(1);
}
stack->capacity = capacity;
stack->top = -1;
stack->data = (int *)malloc(capacity * sizeof(int));
if (stack->data == NULL) {
printf("Memory allocation failed\n");
free(stack);
exit(1);
}
return stack;
}
// Function to push an element onto the stack
void pushStack(Stack *stack, int value) {
if (stack->top == stack->capacity - 1) {
printf("Stack overflow\n");
return;
}
stack->data[++stack->top] = value;
printf("Pushed %d, Stack: ", value);
for (int i = 0; i <= stack->top; i++) {
printf("%d ", stack->data[i]);
}
printf("\n");
}
// Function to pop an element from the stack
int popStack(Stack *stack) {
if (stack->top == -1) {
printf("Stack underflow\n");
return -1;
}
int value = stack->data[stack->top--];
printf("Popped %d, Stack: ", value);
for (int i = 0; i <= stack->top; i++) {
printf("%d ", stack->data[i]);
}
printf("\n");
return value;
}
void evaluateExpression() {
Stack *stack = createStack(10);
pushStack(stack, 10);
pushStack(stack, 2);
int val2 = popStack(stack);
int val1 = popStack(stack);
int result1 = val1 + val2;
pushStack(stack, result1);
pushStack(stack, 8);
pushStack(stack, 3);
val2 = popStack(stack);
val1 = popStack(stack);
int result2 = val1 - val2;
pushStack(stack, result2);
val2 = popStack(stack);
val1 = popStack(stack);
int result3 = val1 * val2;
pushStack(stack, result3);
pushStack(stack, 2);
val2 = popStack(stack);
val1 = popStack(stack);
int finalResult = val1 + val2;
pushStack(stack, finalResult);
// Print final result
printf("Final result: %d\n", popStack(stack));
}
// ############************************************************************############
// ############################### EXERCISE 6 END #####################################
// ####################################################################################
// ####################################################################################
// ################################# MENU START #######################################
// ############************************************************************############
void menuHeader(int exercise){
printf("UNIPI - Data Structures 23-24\n");
if (exercise == 1) {
printf("Matrix Operations:\n");
} else if (exercise == 2) {
printf("Exercise 2 dummy placeholder\n");
} else if (exercise == 3) {
printf("Student directory management options:\n");
printf("1. Add Student\n");
printf("2. Display All Students\n");
printf("3. Display Students by Course\n");
printf("4. Preload sample student data\n");
printf("5. Back to Main Menu\n");
printf("Enter your choice: ");
} else if (exercise == 4) {
printf("Exercise 4 LIFO stack \n");
} else if (exercise == 5) {
printf("Exercise 5 LIFO linked list stack \n");
} else if (exercise == 6) {
printf("Exercise 6 dummy placeholder \n");
}
}
void handleMenuChoice(int choice) {
clearScreen();
switch (choice) {
case 1:
clearScreen();
menuHeader(1);
matrix_operations();
clearInputBuffer();
break;
case 2:
clearScreen();
menuHeader(2);
clearInputBuffer();
break;
case 3:
while (1) {
int subChoice;
clearScreen();
menuHeader(3);
scanf("%d", &subChoice);
switch (subChoice) {
case 1:
handleaddStudent();
break;
case 2:
displayAllStudents();
break;
case 3:
displayStudentsByCourse();
break;
case 4:
studentExamplePreloader();
break;
case 5:
return;
default:
printf("Invalid choice. Please try again.\n");
}
}
case 4:
clearScreen();
menuHeader(4);
performLIFOStackOperations();
clearInputBuffer();
break;
case 5:
clearScreen();
menuHeader(5);
performLIFOlinkedStackOperations();
clearInputBuffer();
break;
case 6:
clearScreen();
menuHeader(6);
evaluateExpression();
clearInputBuffer();
break;
case 7:
clearScreen();
printf("Exiting...\n");
exit(0);
default:
printf("Invalid choice. Please try again.\n");
}
}
int getMenuChoice() {
clearScreen();
int choice;
printf("UNIPI - Data Structures 23-24\n");
printf("Exercise directory \n");
printf("1. Exercise 1 - Matrix Operations\n");
printf("2. Exercise 2 - ------------------\n");
printf("3. Exercise 3 - Student Directory\n");
printf("4. Exercise 4 - LIFO stack (simple)\n");
printf("5. Exercise 5 - LIFO stack (linked lists)\n");
printf("6. Exercise 6 - Expression evaluation\n");
printf("7. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
return choice;
clearInputBuffer();
}
// ############************************************************************############
// ################################## MENU END ########################################
// ####################################################################################
int main() {
//int choice;
while (1){
//choice = getMenuChoice();
//handleMenuChoice(choice);
handleMenuChoice(getMenuChoice());
}
return 0;
}