Skip to content
1 change: 1 addition & 0 deletions homework_6/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ project(homework_6)
set(homeworkName "${PROJECT_NAME}")

add_subdirectory(task_1)
add_subdirectory(task_3)
2 changes: 2 additions & 0 deletions homework_6/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Homework 6

[Task 1. Merge sort](/homework_6/task_1)

[Task 3. Sorted list](/homework_6/task_3)
9 changes: 9 additions & 0 deletions homework_6/task_3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
project("${homeworkName}_task_3")

add_library(sortedList sortedList.c)

add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} sortedList)

add_executable(${PROJECT_NAME}_test test.c)
target_link_libraries(${PROJECT_NAME}_test sortedList)
134 changes: 134 additions & 0 deletions homework_6/task_3/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include <stdbool.h>
#include <stdio.h>

#include "sortedList.h"

typedef enum {
Exit,
Menu,
AddElement,
RemoveElement,
PrintList
} State;

State readCommand(void) {
int command = -1;
if (scanf("%d", &command) != 1) {
command = -1;
}
while (getchar() != '\n') {}
switch (command) {
case 0:
return Exit;
case 1:
return AddElement;
case 2:
return RemoveElement;
case 3:
return PrintList;
default:
printf("Error: unknown command\n");
return Menu;
}
}

State addElementCommand(SortedList *list) {
printf("Enter a number to add: ");
int value = 0;
if (scanf("%d", &value) != 1) {
printf("Error: not a number\n");
return Menu;
}

if (!addElement(list, value)) {
printf("Error: cannot add number\n");
return Menu;
}

return Menu;
}

State removeElementCommand(SortedList *list) {
printf("Enter a number to remove: ");
int value = 0;
if (scanf("%d", &value) != 1) {
printf("Error: not a number\n");
return Menu;
}

if (!removeElement(list, value)) {
printf("Error: cannot remove number; probably, it isn't in the list\n");
return Menu;
}

return Menu;
}

State printListCommand(SortedList *list) {
printf("[ ");
Element *element = getFirst(list);
while (element != NULL) {
printf("%d", getValue(element));

element = getNext(element);
if (element != NULL) {
printf(", ");
}
}
printf(" ]\n");

return Menu;
}

bool doConversation(SortedList *list) {
printf("Sorted list\n");
printf("Available commands: \n");
printf(" 0 - exit;\n");
printf(" 1 - add a number;\n");
printf(" 2 - remove a number;\n");
printf(" 3 - print list.\n");

State state = Menu;
while (true) {
switch (state)
{
case Exit:
return true;

case Menu:
printf("sorted_list> ");
state = readCommand();
break;

case AddElement:
state = addElementCommand(list);
break;

case RemoveElement:
state = removeElementCommand(list);
break;

case PrintList:
state = printListCommand(list);
break;

default:
printf("Error: unknown state\n");
return false;
}
}
}

int main(void) {
SortedList *list = NULL;
if (!createList(&list)) {
printf("Error: allocation failed\n");
return 1;
}

if (!doConversation(list)) {
disposeList(list);
return 1;
}
disposeList(list);
}
118 changes: 118 additions & 0 deletions homework_6/task_3/sortedList.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include "sortedList.h"

#include <stdbool.h>
#include <stdlib.h>

typedef struct Element {
int value;
struct Element *next;
} Element;

typedef struct SortedList {
Element *first;
} SortedList;

bool createList(SortedList **list) {
*list = malloc(sizeof(SortedList));
if (*list == NULL) {
return false;
}

(*list)->first = NULL;
// (*list)->last = NULL;

return true;
}

bool addElement(SortedList *list, int value) {
Element *element = malloc(sizeof(Element));
if (element == NULL) {
return false;
}

element->value = value;
element->next = NULL;

if (list->first == NULL) {
list->first = element;
return true;
}

if (value < getValue(list->first)) {
element->next = list->first;
list->first = element;
return true;
}

Element *last = list->first;
while (last->next != NULL) {
if (getValue(last->next) > value) {
break;
}

last = last->next;
}

element->next = last->next;
last->next = element;

return true;
}

bool removeElement(SortedList *list, int value) {
if (list->first == NULL) {
return false;
}

if (value < getValue(list->first)) {
return false;
}

if (value == getValue(list->first)) {
Element *next = list->first->next;
free(list->first);
list->first = next;
return true;
}

Element *last = list->first;
while (last->next != NULL) {
if (getValue(last->next) == value) {
break;
}

last = last->next;
}

if (last->next == NULL) {
return false;
}

Element *next = last->next->next;
free(last->next);
last->next = next;

return true;
}

Element *getFirst(SortedList *list) {
return list->first;
}

void disposeList(SortedList *list) {
Element *last = list->first;
while (last != NULL) {
Element *next = last->next;
free(last);
last = next;
}
free(list);
}

Element *getNext(Element *element) {
return element->next;
}

int getValue(Element *element) {
return element->value;
}
45 changes: 45 additions & 0 deletions homework_6/task_3/sortedList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <stdbool.h>

/// @brief Element of the sorted list
typedef struct Element Element;

/// @brief List of numbers that remains always sorted
typedef struct SortedList SortedList;

/// @brief Creates new instance of `SortedList`
/// @param list Pointer to store list to
/// @return `true` if created successfully, `false` otherwise (allocation failed)
bool createList(SortedList **list);

/// @brief Adds value to list
/// @param list List to add value to
/// @param value Value to add
/// @return `true` if added successfully, `false` otherwise (allocation failed)
bool addElement(SortedList *list, int value);

/// @brief Removes value from list
/// @param list List to remove value from
/// @param value Value to remove
/// @return `true` if removed successfully, `false` otherwise (element doesn't exist in list)
bool removeElement(SortedList *list, int value);

/// @brief Gets first element in list
/// @param list List to get first element from
/// @return First element in list
Element *getFirst(SortedList *list);

/// @brief Disposes list and all of its elements
/// @param list List to dispose
void disposeList(SortedList *list);

/// @brief Gets element that follows specified element
/// @param element An element
/// @return Element that follows specified element
Element *getNext(Element *element);

/// @brief Gets value of specified element
/// @param element An element
/// @return Value of an element
int getValue(Element *element);
Loading