Advertisement
Solingen

SAKOD_lab4.py

Mar 26th, 2025
324
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.17 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # \author: Артюхин Матфей
  3. # \date_start: 2025-03-22
  4. # \date_end: 2025-03-27
  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
  47.             self.p_cur = p_tmp
  48.             # Организуем циклическую связь
  49.             p_tmp.p_next = p_tmp
  50.             p_tmp.p_prev = p_tmp
  51.         else:
  52.             # Добавление после текущего элемента
  53.             p_tmp.p_next = self.p_cur.p_next
  54.             p_tmp.p_prev = self.p_cur
  55.             self.p_cur.p_next.p_prev = p_tmp
  56.             self.p_cur.p_next = p_tmp
  57.             self.p_cur = p_tmp
  58.  
  59.     def remove(self, item):
  60.         """
  61.        \brief Функция удаления элемента из списка по значению.
  62.  
  63.        \param item [in] - значение удаляемого элемента.
  64.        \retval None
  65.        """
  66.         if self.p_first is None:
  67.             return
  68.  
  69.         p_tmp = self.p_first
  70.         while True:
  71.             if p_tmp.data == item:
  72.                 if p_tmp.p_next == p_tmp:
  73.                     self.p_first = None
  74.                     self.p_cur = None
  75.                 else:
  76.                     if p_tmp == self.p_first:
  77.                         self.p_first = p_tmp.p_next
  78.                     p_tmp.p_prev.p_next = p_tmp.p_next
  79.                     p_tmp.p_next.p_prev = p_tmp.p_prev
  80.                     if p_tmp == self.p_cur:
  81.                         self.p_cur = p_tmp.p_prev
  82.                 return
  83.             p_tmp = p_tmp.p_next
  84.             if p_tmp == self.p_first:
  85.                 break
  86.  
  87.     def print_list(self):
  88.         """
  89.        \brief Печать элементов списка.
  90.  
  91.        \retval None
  92.        """
  93.         if self.p_first is None:
  94.             print("Список пуст")
  95.             return
  96.         print("Элементы списка:", end=" ")
  97.         p_tmp = self.p_first
  98.         print(p_tmp.data, end=" ")
  99.         p_tmp = p_tmp.p_next
  100.         while p_tmp != self.p_first:
  101.             print(p_tmp.data, end=" ")
  102.             p_tmp = p_tmp.p_next
  103.         print()
  104.  
  105.     def sort(self):
  106.         """
  107.        \brief Сортировка списка методом пузырька.
  108.  
  109.        \retval None
  110.        """
  111.         if self.p_first is None or self.p_first.p_next == self.p_first:
  112.             return
  113.  
  114.         swapped = True
  115.         while swapped:
  116.             swapped = False
  117.             current = self.p_first
  118.             while True:
  119.                 next_node = current.p_next
  120.                 if next_node == self.p_first:
  121.                     break
  122.                 if current.data > next_node.data:
  123.                     current.data, next_node.data = next_node.data, current.data
  124.                     swapped = True
  125.                 current = next_node
  126.  
  127.     def is_sorted(self):
  128.         """
  129.        \brief Проверка отсортированности списка по возрастанию.
  130.  
  131.        \retval bool - True, если список отсортирован
  132.        """
  133.         if self.p_first is None:
  134.             return True
  135.         current = self.p_first
  136.         while True:
  137.             next_node = current.p_next
  138.             if next_node == self.p_first:
  139.                 break
  140.             if current.data > next_node.data:
  141.                 return False
  142.             current = next_node
  143.         return True
  144.  
  145.     def get_list_as_array(self):
  146.         """
  147.        \brief Преобразование списка в массив.
  148.  
  149.        \retval list - массив данных списка
  150.        """
  151.         arr = []
  152.         if self.p_first is None:
  153.             return arr
  154.         p_tmp = self.p_first
  155.         arr.append(p_tmp.data)
  156.         p_tmp = p_tmp.p_next
  157.         while p_tmp != self.p_first:
  158.             arr.append(p_tmp.data)
  159.             p_tmp = p_tmp.p_next
  160.         return arr
  161.  
  162.     def binary_search(self, value):
  163.         """
  164.        \brief Бинарный поиск значения в отсортированном списке.
  165.  
  166.        \param value [in] - искомое значение
  167.        \retval tuple - (значение, индекс) или (None, -1) при ошибке
  168.        """
  169.         if not self.is_sorted():
  170.             return None, -1
  171.         arr = self.get_list_as_array()
  172.         left, right = 0, len(arr) - 1
  173.         while left <= right:
  174.             mid = (left + right) // 2
  175.             if arr[mid] == value:
  176.                 return arr[mid], mid
  177.             elif arr[mid] < value:
  178.                 left = mid + 1
  179.             else:
  180.                 right = mid - 1
  181.         return None, -1
  182.  
  183. def main():
  184.     """
  185.    \brief Основная функция с меню управления.
  186.  
  187.    \retval None
  188.    """
  189.     pList = DoublyLinkedList()
  190.     while True:
  191.         print("\nПожалуйста, введите номер команды:")
  192.         print("0 - Выход")
  193.         print("1 - Добавить элемент")
  194.         print("2 - Удалить элемент")
  195.         print("3 - Напечатать список")
  196.         print("4 - Отсортировать список")
  197.         print("5 - Бинарный поиск")
  198.         try:
  199.             menuPos = int(input("Введите команду: "))
  200.         except ValueError:
  201.             print("Некорректный ввод.")
  202.             continue
  203.  
  204.         if menuPos == 0:
  205.             print("... Завершение работы ...")
  206.             break
  207.         elif menuPos == 1:
  208.             data = input("-- Введите значение элемента: ")
  209.             try:
  210.                 data = int(data)
  211.             except ValueError:
  212.                 pass
  213.             pList.add(data)
  214.         elif menuPos == 2:
  215.             data = input("-- Введите значение элемента: ")
  216.             try:
  217.                 data = int(data)
  218.             except ValueError:
  219.                 pass
  220.             pList.remove(data)
  221.         elif menuPos == 3:
  222.             pList.print_list()
  223.         elif menuPos == 4:
  224.             pList.sort()
  225.             print("Список отсортирован.")
  226.         elif menuPos == 5:
  227.             if pList.is_sorted():
  228.                 data = input("-- Введите искомое значение: ")
  229.                 try:
  230.                     data = int(data)
  231.                 except ValueError:
  232.                     print("Ошибка ввода!")
  233.                     continue
  234.                 result, index = pList.binary_search(data)
  235.                 if result is not None:
  236.                     print(f"Найдено: {result} (индекс {index})")
  237.                 else:
  238.                     print("Элемент не найден.")
  239.             else:
  240.                 print("Список не отсортирован!")
  241.         else:
  242.             print("Неверная команда!")
  243.  
  244. if __name__ == "__main__":
  245.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement