Advertisement
Solingen

SAKOD_lab2.py

Feb 26th, 2025
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.77 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # \author: Артюхин Матфей
  3. # \date_start: 2025-02-24
  4. # \date_end: 2025-02-26
  5.  
  6. # Класс Node - элемент двунаправленного списка
  7. class Node:
  8.     """
  9.    \brief Класс Node представляет элемент двунаправленного списка.
  10.    
  11.    \param data [in]       - данные элемента (числовые, строковые, даты и т.п.)
  12.    \param p_next [in/out] - ссылка на следующий элемент списка
  13.    \param p_prev [in/out] - ссылка на предыдущий элемент списка
  14.    """
  15.     def __init__(self, data):
  16.         # Инициализация данных элемента
  17.         self.data = data  # данные элемента
  18.         self.p_next = None  # указатель на следующий элемент
  19.         self.p_prev = None  # указатель на предыдущий элемент
  20.  
  21. # Класс DoublyLinkedList - реализация двунаправленного списка
  22. class DoublyLinkedList:
  23.     """
  24.    \brief Класс DoublyLinkedList реализует двунаправленный список с операциями добавления,
  25.           удаления, печати и сортировки списка.
  26.    
  27.    \param p_first [in/out] - указатель на первый элемент списка
  28.    \param p_cur [in/out]   - указатель на текущий элемент списка (для удобства добавления)
  29.    """
  30.     def __init__(self):
  31.         # Инициализация указателей списка
  32.         self.p_first = None  # указатель на первый элемент списка
  33.         self.p_cur = None    # указатель на текущий элемент списка
  34.  
  35.     def add(self, item):
  36.         """
  37.        \brief Функция добавления элемента в список.
  38.        
  39.        \param item [in] - значение добавляемого элемента.
  40.        \retval None
  41.        """
  42.         # Создаем новый элемент списка с заданным значением
  43.         p_tmp = Node(item)
  44.         # Если список пуст, новый элемент становится первым
  45.         if self.p_first is None:
  46.             self.p_first = p_tmp  # устанавливаем p_first
  47.             self.p_cur = p_tmp    # устанавливаем p_cur
  48.             # Организуем циклическую связь для одиночного элемента
  49.             p_tmp.p_next = p_tmp  # ссылка на самого себя как на следующий элемент
  50.             p_tmp.p_prev = p_tmp  # ссылка на самого себя как на предыдущий элемент
  51.         else:
  52.             # Добавление нового элемента после текущего элемента p_cur
  53.             p_tmp.p_next = self.p_cur.p_next  # назначаем ссылку на следующий элемент
  54.             p_tmp.p_prev = self.p_cur         # назначаем ссылку на предыдущий элемент
  55.             # Комментарий: обновляем ссылку предыдущего элемента у p_cur.p_next
  56.             self.p_cur.p_next.p_prev = p_tmp
  57.             # Обновляем ссылку следующего элемента у текущего элемента
  58.             self.p_cur.p_next = p_tmp
  59.             # Перемещаем указатель p_cur на вновь добавленный элемент
  60.             self.p_cur = p_tmp
  61.         # Конец функции add
  62.  
  63.     def remove(self, item):
  64.         """
  65.        \brief Функция удаления первого найденного элемента из списка по значению.
  66.        
  67.        \param item [in] - значение удаляемого элемента.
  68.        \retval None
  69.        """
  70.         # Если список пуст, удалять нечего
  71.         if self.p_first is None:
  72.             return
  73.  
  74.         p_tmp = self.p_first  # начинаем поиск с первого элемента
  75.         # Перебор элементов списка
  76.         while True:
  77.             # Если найден элемент с требуемым значением
  78.             if p_tmp.data == item:
  79.                 # Если список содержит только один элемент
  80.                 if p_tmp.p_next == p_tmp:
  81.                     self.p_first = None  # обнуляем указатель на первый элемент
  82.                     self.p_cur = None    # обнуляем указатель на текущий элемент
  83.                 else:
  84.                     # Если удаляется первый элемент списка
  85.                     if p_tmp == self.p_first:
  86.                         self.p_first = p_tmp.p_next  # переназначаем p_first
  87.                     # Обновляем связи соседних элементов
  88.                     p_tmp.p_prev.p_next = p_tmp.p_next
  89.                     p_tmp.p_next.p_prev = p_tmp.p_prev
  90.                     # Если удаляется текущий элемент, обновляем указатель p_cur
  91.                     if p_tmp == self.p_cur:
  92.                         self.p_cur = p_tmp.p_prev
  93.                 # Элемент найден и удален, выходим из функции
  94.                 return
  95.             # Переходим к следующему элементу
  96.             p_tmp = p_tmp.p_next
  97.             # Если вернулись к первому элементу, значит, элемент не найден
  98.             if p_tmp == self.p_first:
  99.                 break
  100.         # Конец функции remove
  101.  
  102.     def print_list(self):
  103.         """
  104.        \brief Функция печати элементов списка на экран.
  105.        
  106.        \retval None
  107.        """
  108.         # Если список пуст, выводим сообщение
  109.         if self.p_first is None:
  110.             print("Список пуст")
  111.             return
  112.  
  113.         # Начинаем печать с первого элемента
  114.         print("Элементы списка:", end=" ")
  115.         p_tmp = self.p_first
  116.         # Выводим данные первого элемента
  117.         print(p_tmp.data, end=" ")
  118.         p_tmp = p_tmp.p_next
  119.         # Печатаем остальные элементы до полного обхода списка
  120.         while p_tmp != self.p_first:
  121.             print(p_tmp.data, end=" ")
  122.             p_tmp = p_tmp.p_next
  123.         print()  # переход на новую строку после печати списка
  124.         # Конец функции print_list
  125.  
  126.     def sort(self):
  127.         """
  128.        \brief Функция сортировки списка методом пузырьковой сортировки.
  129.        
  130.        \retval None
  131.        """
  132.         # Если список пуст или содержит один элемент, сортировать нечего
  133.         if self.p_first is None or self.p_first.p_next == self.p_first:
  134.             return
  135.  
  136.         swapped = True
  137.         while swapped:
  138.             swapped = False
  139.             current = self.p_first
  140.             while True:
  141.                 next_node = current.p_next
  142.                 if next_node == self.p_first:
  143.                     break  # Дошли до начала списка
  144.                 if current.data > next_node.data:
  145.                     # Меняем данные местами
  146.                     current.data, next_node.data = next_node.data, current.data
  147.                     swapped = True
  148.                 current = next_node
  149.         # Конец функции sort
  150.  
  151. def main():
  152.     """
  153.    \brief Основная функция программы, реализующая меню для работы со списком.
  154.    
  155.    \retval None
  156.    """
  157.     # Инициализируем двунаправленный список
  158.     pList = DoublyLinkedList()
  159.  
  160.     while True:
  161.         # Вывод меню для пользователя
  162.         print("\nПожалуйста, введите номер команды:")
  163.         print("0 - Выход")
  164.         print("1 - Добавить элемент")
  165.         print("2 - Удалить элемент")
  166.         print("3 - Напечатать список")
  167.         print("4 - Отсортировать список")
  168.         # Ввод команды от пользователя
  169.         try:
  170.             menuPos = int(input("Введите команду: "))
  171.         except ValueError:
  172.             # Если ввод некорректен, выводим сообщение и повторяем цикл
  173.             print("Некорректный ввод. Попробуйте снова.")
  174.             continue
  175.  
  176.         # Обработка выбора команды
  177.         if menuPos == 0:
  178.             # Выход из программы
  179.             print("... Завершение работы ...")
  180.             break
  181.         elif menuPos == 1:
  182.             # Добавление элемента в список
  183.             data = input("-- Введите значение элемента (добавление): ")
  184.             # Попытка преобразования введенных данных в целое число
  185.             try:
  186.                 data = int(data)
  187.             except ValueError:
  188.                 # Если преобразование не удалось, оставляем строковое значение
  189.                 pass
  190.             pList.add(data)
  191.         elif menuPos == 2:
  192.             # Удаление элемента из списка
  193.             data = input("-- Введите значение элемента (удаление): ")
  194.             try:
  195.                 data = int(data)
  196.             except ValueError:
  197.                 pass
  198.             pList.remove(data)
  199.         elif menuPos == 3:
  200.             # Печать списка
  201.             pList.print_list()
  202.         elif menuPos == 4:
  203.             # Сортировка списка
  204.             pList.sort()
  205.             print("Список отсортирован.")
  206.         else:
  207.             # Обработка неверного выбора команды
  208.             print("!!! Неверный номер команды !!!")
  209.     # Конец основного цикла меню
  210.  
  211. # Точка входа в программу
  212. if __name__ == "__main__":
  213.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement