Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.25)

project(C_Homework C)

add_subdirectory(src/TestTask)

enable_testing()

add_compile_options(-Wall -Wextra -Wpedantic)
8 changes: 8 additions & 0 deletions src/TestTask/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_library(list list.c)

add_executable(sortedList
sortedList.c
testSortedList.c
)
target_link_libraries(sortedList PRIVATE list)

173 changes: 173 additions & 0 deletions src/TestTask/list.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#include "list.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

// структура обычного элемента в списке
struct ListNode {
int value;
struct ListNode* next;
};

// структура содержащая указатель на первый элемент списка
struct List {
ListNode* head;
};

List* newList()
{
List* list = calloc(1, sizeof(*list));
return list;
}

bool insert(List* list, int index, int value)
{
if (list == NULL || index < 0) {
return false;
}
if (index == 0) {
ListNode* newNode = malloc(sizeof(ListNode));
newNode->value = value;
newNode->next = list->head;
list->head = newNode;
return true;
}
ListNode* current = list->head;
int counter = 0;
while (current != NULL) {
if (counter == index - 1) {
ListNode* newNode = malloc(sizeof(ListNode));
newNode->value = value;
newNode->next = current->next;
current->next = newNode;
return true;
}
current = current->next;
counter++;
}
return false;
}

int get(List* list, int index)
{
if (list == NULL || isEmpty(list) || index < 0)
return -1;
if (index == 0) {
return list->head->value;
}
ListNode* current = list->head;
int counter = 0;
while (current != NULL) {
if (counter == index) {
return current->value;
}
current = current->next;
counter++;
}
return -1;
}

bool removeElement(List* list, int index)
{
if (list == NULL || isEmpty(list) || index < 0) {
return false;
}
ListNode* current = list->head;
if (index == 0) {
list->head = current->next;
free(current);
return true;
}
int counter = 0;
while (current != NULL) {
if (counter == index - 1) {
if (current->next == NULL)
return false;
ListNode* nodeToDelete = current->next;
current->next = nodeToDelete->next;
free(nodeToDelete);
return true;
}
current = current->next;
counter++;
}
return false;
}

bool deleteList(List* list)
{
if (list == NULL || isEmpty(list)) {
return false;
}
while (!isEmpty(list)) {
removeElement(list, 0);
}
free(list);
return true;
}

void printList(List* list)
{
if (list == NULL || isEmpty(list)) {
printf("Список пустой\n");
return;
}

ListNode* current = list->head;
while (current != NULL) {
printf("%d ", current->value);
current = current->next;
}
printf("\n");
}

bool isEmpty(List* list)
{
return list->head == NULL;
}

bool insert_sorted_in_ascending_order(List* list, int value)
{
if (list == NULL) {
return false;
}
// случай еще незаполненного списка
if (isEmpty(list)) {
return insert(list, 0, value);
}
ListNode* current = list->head;
int counter = 0;
// если элемент самый маленький и его надо вставить в начало
if (current->value > value) {
return insert(list, 0, value);
}
while (current != NULL && current->next != NULL) {
if ((current->next->value > value) && (current->value <= value)) {
return (insert(list, counter + 1, value));
}
current = current->next;
counter++;
}
// если программа достигла этой строчки, то значит что элемент больше всех
// остальных
return insert(list, counter + 1, value);
}

int getLength(List* list)
{
if (list == NULL || isEmpty(list)) {
return -1;
}
int counter = 0;
ListNode* current = list->head;
do {
counter++;
current = current->next;
} while (current != NULL);
return counter;
}

bool oneElement(List* list)
{
return list->head->next == NULL;
}
95 changes: 95 additions & 0 deletions src/TestTask/list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#pragma once
#include <stdbool.h>

// структура обычного элемента в списке
typedef struct ListNode ListNode;

// структура содержащая указатель на первый элемент списка
typedef struct List List;

/*
* функция создания нового списка
* ничего не принимает
* возвращает указатель на объект типа List
*/
List* newList();

/*
* функция вставки элемента по заданному индексу
* принимает на вход указатель на объект типа List, желаемый индекс и значение
* возвращает булевое значение, сообщающее, удачно ли прошла операция
*/
bool insert(List* list, int index, int value);

/*
* функция просмотра элемента списка по индексу
* принимает указатель на объект типа List и индекс
* возвращает value элемента
* если что-то пошло не так, вернет -1
*/
int get(List* list, int index);

/*
* функция удаления элемента по индексу
* принимает указатель на объект типа List и индекс элемента
* возвращает булевое значние, сообщающее, удачно ли прошла операция
* внутри себя освобождает память удаляемого элемента
*/
bool removeElement(List* list, int index);

/*
* функция соединения двух списков
* подразумевается, что пользователь передает в ф. два существующих непустых списка
* возвращает указатель типа List на первый элемент первого переданного списка
* !!на данный момент нуждается в доработке!!
*/
List* appendLists(List* list1, List* list2);

/*
* функция удаления всего списка
* принимает указатель на объект типа List
* внутри себя вызывает функцию removeElement
* возвращает булевое значение, удачно ли прошла операция
*/
bool deleteList(List* list);

/*
* функция вывода списка в консоль
* принимает только указаетль на список
* ничего не возвращает
* печатает элементы списка через пробел
* в случае переданного пустого или несуществующего списка сообщает об этом пользователю
*/
void printList(List* list);

/*
* функция которая вставляет элемент в определенное место так, чтобы список всегда оставался отсортированным
* принимает значение и список
* возвращает булевое значение об успешной или неуспешной вставке
*/
bool insert_sorted_in_ascending_order(List* list, int value);

/*
* функция проверки, пустой ли список
* возвращает true если пустой, false, если нет
* на вход принимает указатель на список
*/
bool isEmpty(List* list);

/*
* функция, возвращающая длину списка
* принимает на вход указатель на список
* проходится по всем элементам
* возвращает его длину
*/
int getLength(List* list);

/*
* функция проверки, один ли элемент в списке
* возвращает true если да, false, если нет
* на вход принимает указатель на список
*/
bool oneElement(List* list);

// функция запуска тестов
void runTests();
105 changes: 105 additions & 0 deletions src/TestTask/sortedList.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include "list.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

void printMenu()
{
printf("\n=== МЕНЮ КОМАНД ===\n");
printf("1 - Добавить элемент (с сортировкой по возрастанию)\n");
printf("2 - Удалить элемент по индексу\n");
printf("3 - Вывести список\n");
printf("0 - Выход из программы\n");
}

void clearInputBuffer()
{
int c;
while ((c = getchar()) != '\n') {
}
}

void addElementInList(List *list)
{
int element = 0;
printf("Введите элемент который хотите добавить\n");

if (scanf("%d", &element) != 1) {
printf("Ошибка: введено некорректное значение!\n");
clearInputBuffer();
return;
}
clearInputBuffer();
insert_sorted_in_ascending_order(list, element);
printf("Элемент успешно добавлен\n");
}

void removeElemetFromList(List *list)
{
int index = 0;
printf("Введите индекс элемента, который хотите удалить: ");
if (scanf("%d", &index) != 1) {
printf("Ошибка: введен некорректный индекс!\n");
clearInputBuffer();
return;
}
clearInputBuffer();

if (removeElement(list, index)) {
printf("Элемент успешно удален.\n");
} else {
printf("Что-то пошло не так. Возможно введен неправильный индекс.\n");
}
}

void printTheList(List *list)
{
printf("Список элементов:\n");
printList(list);
}

void handleCommands()
{
printf("Вводите команды. После каждой введенной команды нажимайте Enter\n");
printf("Чтобы завершить работу с программой, введите 0\n\n");
List *list = newList();
int command = 0;
while (1) {
printf("Введите команду: ");
if (scanf("%d", &command) != 1) {
printf("Ошибка: пожалуйста, введите число от 0 до 3!\n");
clearInputBuffer();
continue; // Пропускаем остаток цикла и начинаем заново
}
clearInputBuffer();
if (command == 0) {
break;
}
switch (command) {
case 1:
addElementInList(list);
break;
case 2:
removeElemetFromList(list);
break;
case 3:
printTheList(list);
break;
default:
printf("Вероятно, такой команды не существует\n");
}
}
deleteList(list);
printf("Работа с программой завершена. Память очищена\n");
}

int main(int argc, char *argv[])
{
if (argc == 2 && strcmp(argv[1], "--test") == 0) {
runTests();
return 0;
}
printMenu();
handleCommands();
return 0;
}
Loading