Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пособие часть1.doc
Скачиваний:
22
Добавлен:
01.03.2025
Размер:
6.94 Mб
Скачать

2.4.3. Двунаправленный список (список л2)

В списках Л2 базовые операции также определяются относительно текущего элемента (см. рис. 2.9), поэтому основной набор операций совпадает со списками Л1. Дополнительная возможность состоит в обходе списка не только в прямом, но и обратном направлении. Такая возможность требуется, например, при реализации просмотра или редактирования текстовых файлов с использованием списков и многих других алгоритмах.

Для того, чтобы сделать возможным движение по списку в двух направлениях, необходимо добавить к тем операциям, которые определены для однонаправленного списка, еще три дополнительных операции:

  • сделать текущим последний элемент (встать в конец списка);

  • сделать текущим предыдущий элемент (продвинуться назад на один элемент):

  • проверить состояние начала списка при переходе к предыдущему элементу, что может случиться, если текущим был первый элемент.

Формальную спецификацию списков Л1 и Л2 можно выполнить самостоятельно, аналогично представленной выше спецификации для стеков и очередей. В следующем разделе, посвященном реализации списков, формальная спецификация будет выполнена средствами языка программирования.

2.4.4. Циклический (кольцевой) список

В обычных линейных списках последний элемент завершает список (не имеет следующего за ним элемента), а первый означает начало списка (не имеет предыдущего). Существует особый вид списков, называемых циклическими, в которых для последнего элемента следующим является первый, а для первого предыдущим является пооследний. Фактически связи элементов образуют кольцо, поэтому иначе такие списки называются кольцевыми. Такие списки используются, например, при реализации некоторых элементов пользовательского интерфейса, допустим, меню (продвигаясь вперед от последнего пункта мы снова попадаем в первый).

Циклические списки имеют некоторые преимущества перед линейными, поскольку в самом списке содержатся указатели на все элементы без исключения. Мы уже пользовались этим преимуществом при реализации очереди с помощью циклического списка, при этом сэкономили на одном дополнительном указателе.

В циклических списках всегда можно попасть в любую позицию, двигаясь от любого элемента только в одном направлении. Для циклических списков легче, чем для линейных, выполняются некоторые операции, например, слияние двух списков, при этом достаточно иметь только по одному дополнительному указателю на произвольный элемент каждого списка.

Вообще в кольцевых списках понятие первого и последнего элемента весьма условно, но обычно все же выделяют особый легкораспознаваемый элемент как начало списка для удобства реализации. Такой узел называют заголовком списка [Кнут].

Если говорить о формальной спецификации операций над кольцевыми списками, то набор базовых операций соответствует набору для линейных списков Л1 или Л2 (за исключением проверки выхода за границы списка — в кольцевом списке движение выполняется по кругу). Однако семантика основных операций немного отличается от линейных списков, например, для операций вставки и удаления отсутствует необходимость рассматривать отдельные случаи, связанные с началом и концом списка.