diff --git a/py_data_structures/array.py b/py_data_structures/array.py new file mode 100644 index 00000000..5e50822f --- /dev/null +++ b/py_data_structures/array.py @@ -0,0 +1,124 @@ +from typing import Any, List + + +class Array: + """ + ru: Класс для реализации массива как структуры данных. + en: A class for implementing an array as a data structure. + """ + + def __init__(self, initial_capacity: int = 10): + """ + Инициализация массива с заданной емкостью. | Initialization of an array with a specified capacity. + :param initial_capacity: начальный размер массива | The initial size of the array + """ + self.capacity = initial_capacity # Максимальная емкость / Maximum capacity + self.size = 0 # Текущий размер (количество элементов) | Current size (number of elements) + self.array = [None] * self.capacity # Массив фиксированной длины | Fixed-length array + + def __check_index(self, index: int): + """ + Проверяет, является ли индекс допустимым. | Checks whether the index is valid. + """ + if index < 0 or index >= self.size: + raise IndexError("Индекс вне диапазона | The index is out of range") + + def add(self, value: Any) -> None: + """ + Добавляет элемент в массив. Если массив заполнен, увеличивает емкость. | + Adds an element to the array. If the array is full, it increases the capacity. + """ + if self.size == self.capacity: + self.__resize() + + self.array[self.size] = value + self.size += 1 + + def insert(self, index: int, value: Any) -> None: + """ + Вставляет элемент в заданную позицию. | Inserts the element into the specified position. + :param index: Позиция для вставки | Insertion position + :param value: Значение для вставки | Value to insert + """ + if self.size == self.capacity: + self.__resize() + + if index < 0 or index > self.size: + raise IndexError("Индекс вне диапазона | The index is out of range") + + # Сдвигаем элементы вправо / Moving the elements to the right + for i in range(self.size, index, -1): + self.array[i] = self.array[i - 1] + + self.array[index] = value + self.size += 1 + + def remove(self, index: int) -> None: + """ + Удаляет элемент по индексу. | Deletes an element by index. + """ + self.__check_index(index) + + # Сдвигаем элементы влево | Moving the elements to the left + for i in range(index, self.size - 1): + self.array[i] = self.array[i + 1] + + self.array[self.size - 1] = None + self.size -= 1 + + def get(self, index: int) -> Any: + """ + Возвращает элемент по индексу. | Returns the element by index. + """ + self.__check_index(index) + return self.array[index] + + def set(self, index: int, value: Any) -> None: + """ + Обновляет значение элемента по индексу. | Updates the value of the element by index. + """ + self.__check_index(index) + self.array[index] = value + + def find(self, value: Any) -> int: + """ + Возвращает индекс первого вхождения значения в массиве. Если значение не найдено, возвращает -1. | + Returns the index of the first occurrence of the value in the array. + If the value is not found, it returns -1. + """ + for i in range(self.size): + if self.array[i] == value: + return i + return -1 + + def traverse(self) -> List[Any]: + """ + Перебирает все элементы массива и возвращает их в виде списка. | + Iterates through all the elements of the array and returns them as a list. + """ + return [self.array[i] for i in range(self.size)] + + def __resize(self) -> None: + """ + Увеличивает емкость массива в два раза. | + Increases the capacity of the array by two times. + """ + self.capacity *= 2 + new_array = [None] * self.capacity + for i in range(self.size): + new_array[i] = self.array[i] + self.array = new_array + + def __len__(self) -> int: + """ + Возвращает текущий размер массива. | + Returns the current size of the array. + """ + return self.size + + def __str__(self) -> str: + """ + Возвращает строковое представление массива. | + Returns the string representation of an array. + """ + return f"Array({self.traverse()})" diff --git a/py_data_structures/linked_list.py b/py_data_structures/linked_list.py new file mode 100644 index 00000000..4861bd78 --- /dev/null +++ b/py_data_structures/linked_list.py @@ -0,0 +1,129 @@ +class Node: + """ + Класс узла связного списка + Node class for a linked list + """ + def __init__(self, data): + self.data = data # Данные узла / Node data + self.next = None # Ссылка на следующий узел / Pointer to the next node + + +class LinkedList: + """ + Класс для связного списка + Class for a linked list + """ + def __init__(self): + self.head = None # Головной узел / Head node + + def is_empty(self): + """Проверяет, пуст ли список. Checks if the list is empty.""" + return self.head is None + + def add_to_head(self, data): + """ + Добавляет элемент в начало списка. + Adds an element to the head of the list. + """ + new_node = Node(data) + new_node.next = self.head + self.head = new_node + + def add_to_tail(self, data): + """ + Добавляет элемент в конец списка. + Adds an element to the tail of the list. + """ + new_node = Node(data) + if self.is_empty(): + self.head = new_node + else: + current = self.head + while current.next: + current = current.next + current.next = new_node + + def remove(self, data): + """ + Удаляет узел с заданным значением. + Removes the node with the specified value. + """ + if self.is_empty(): + return False + + if self.head.data == data: + self.head = self.head.next + return True + + current = self.head + while current.next and current.next.data != data: + current = current.next + + if current.next: + current.next = current.next.next + return True + + return False + + def find(self, data): + """ + Находит узел с заданным значением. + Finds a node with the specified value. + """ + current = self.head + while current: + if current.data == data: + return True + current = current.next + return False + + def size(self): + """ + Возвращает количество элементов в списке. + Returns the number of elements in the list. + """ + count = 0 + current = self.head + while current: + count += 1 + current = current.next + return count + + def print_list(self): + """ + Печатает все элементы списка. + Prints all elements of the list. + """ + current = self.head + while current: + print(current.data, end=" -> ") + current = current.next + print("None") + + +# Пример работы связного списка +if __name__ == "__main__": + linked_list = LinkedList() + + # Добавление элементов + linked_list.add_to_head(3) + linked_list.add_to_head(2) + linked_list.add_to_tail(4) + + print("Связный список после добавления элементов:") + linked_list.print_list() + + # Удаление элемента + linked_list.remove(2) + print("Связный список после удаления элемента 2:") + linked_list.print_list() + + # Поиск элемента + print("Элемент 3 найден:", linked_list.find(3)) + print("Элемент 5 найден:", linked_list.find(5)) + + # Размер списка + print("Размер связного списка:", linked_list.size()) + + # Проверка пустоты + print("Список пустой?", linked_list.is_empty()) \ No newline at end of file diff --git a/py_data_structures/stack.py b/py_data_structures/stack.py new file mode 100644 index 00000000..7585fdbd --- /dev/null +++ b/py_data_structures/stack.py @@ -0,0 +1,80 @@ +class Stack: + """ + Основные операции стека: | Basic stack operations: + push() — добавление элемента в вершину стека. | adding an element to the top of the stack. + pop() — удаление и возврат верхнего элемента. | deleting and returning the top element. + peek() — просмотр верхнего элемента без его удаления. | viewing the top element without deleting it. + is_empty() — проверка, пуст ли стек. | checking if the stack is empty. + size() — возвращает количество элементов в стеке. | returns the number of items in the stack. + """ + def __init__(self): + """Инициализация пустого стека. | Initializing an empty stack.""" + self.items = [] + + def push(self, item): + """ + Добавляет элемент на вершину стека. + :param item: Добавляемый элемент | + Adds an element to the top of the stack. + :param item: The item to add + """ + self.items.append(item) + + def pop(self): + """ + Удаляет и возвращает верхний элемент стека. + :return: Верхний элемент стека + :raises IndexError: Если стек пуст | + Deletes and returns the top element of the stack. + :return: The top element of the stack + :raises IndexError: If the stack is empty + """ + if self.is_empty(): + raise IndexError("pop from empty stack") + return self.items.pop() + + def peek(self): + """ + Возвращает верхний элемент стека без его удаления. + :return: Верхний элемент стека + :raises IndexError: Если стек пуст + Returns the top element of the stack without deleting it. + :return: The top element of the stack + :raises IndexError: If the stack is empty + """ + if self.is_empty(): + raise IndexError("peek from empty stack") + return self.items[-1] + + def is_empty(self): + """ + Проверяет, пуст ли стек. + :return: True, если стек пуст; иначе False + Checks if the stack is empty. + :return: True if the stack is empty; otherwise False + """ + return len(self.items) == 0 + + def size(self): + """ + Возвращает количество элементов в стеке. + :return: Количество элементов + Returns the number of items in the stack. + :return: Number of elements + """ + return len(self.items) + + def clear(self): + """ + Очищает стек. | Clears the stack. + """ + self.items = [] + + def __str__(self): + """ + Возвращает строковое представление стека. + :return: Строка с элементами стека + Returns the string representation of the stack. + :return: A string with glass elements + """ + return f"Stack({self.items})"