Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SAOD..doc
Скачиваний:
142
Добавлен:
11.05.2015
Размер:
959.49 Кб
Скачать

5.2 Реализация связного списка массивом

Для того, чтобы нагляднее представить себе работу со связанными списками (основные её этапы: – пере­ход к соседним элементам; – включение элемента; – исключение элемента), представим связный список его простейшей моделью – массивом записей (структур), в которой есть дополнительное поле – указатель на сле­дующую запись. (Аналогичную модель можно рассмотреть и для последовательных списков, это очень просто проделать самим). В данном случае указатель будет иметь значение индекса следующего элемента в массиве записей.

CONST MS = 100; TYPE SP = RECORD

INF : T0; { T0 - базовый тип; напр., пусть INF:CHAR; }

LINK : INTEGER

END; VAR SPISOK : ARRAY[1..MS] OF SP;

NACH : INTEGER;

K, I, J : INTEGER;

C : CHAR;

free

nach

12 3

0

4

5

7

H0 гт

6

9

7 8 9 10

11

12

8 H 110 H |2

11

12

H=B

0

Рис. 12

Установлена логическая связь между элементами списка в порядке 3–5–6–9–2 (см. указатели). Признак последнего элемента – значение указателя равно 0. Индекс начала списка находится в перемен­ной nach. Элементы массива 1, 4, 7, 8, 10, 11, 12 в список не включены.

Теперь посмотрим, как будут осуществляться основные операции над списком, заданным в таком виде.

Переход к следующему элементу списка

Пусть i - индекс текущего элемента. Тогда индекс следующего элемента получим:

J := SPISOK[I].LINK;

C := SPISOK[I].INF; - значение I-го элемента

Обратим внимание на то, что связь с предыдущим элементом потеряна совершенно.

Просмотр всего списка с начала

I := NACH;

WHILE I <> 0 DO BEGIN

C := SPISOK[I].INF;

{ обработка c }

I := SPISOK[I].LINK; END;

Просматривать список можно с начала или с промежуточного элемента, но только в сторону конца списка.

Поиск нужного элемента

I := NACH;

WHILE (C <> '...') AND (I <> 0) DO BEGIN

C := SPISOK[I].INF;

I := SPISOK[I].LINK; END; IF C <> '...' THEN { элемент не найден }

Включение в список

Пусть элемент массива с индексом j надо включить в список после элемент i. Например, j = 11, i = 6. Тогда

SPISOK[J].INF := C; занести информацию

SPISOK[J].LINK := SPISOK[I].LINK; занести указатель

SPISOK[I].LINK := J; сменить указатель предыдущего элемента Включение и исключение производится после элемента с заданным номером.

Исключение элемента из списка

Пусть надо исключить из списка элемент, стоящий после элемента с индексом i. Например, i = 3 (следова­тельно, нужно исключить элемент с j = 5). Для этого нужно указатель элемента j перенести в указатель элемен­та i.

J := SPISOK[I].LINK; нашли индекс удаляемого элемента

SPISOK[I].LINK := SPISOK[J].LINK; перенесли указатель

C := SPISOK[J].INF; сохранили информацию

Обратим внимание на цикличность и зеркальность операций включения и исключения элементов из спи­ска.

Мы пока не останавливались на вопросе о том, как определяется индекс свободного элемента для включе­ния в список и как распорядиться освобожденным элементом списка.

Освобожденный элемент является "мусором". Выход из положения – все свободные элементы массива связать в еще один список – список свободного пространства.

Теперь перед операцией добавления в основной список нужно взять один элемент из списка свободного пространства (обычно первый – признак стека).

После операции удаления из основного списка надо добавить операцию включения освобожденного эле­мента в список свободного пространства (в начало этого списка – стек).

Список свободного пространства используется как стек. Теперь две последние операции выполняются сле­дующим образом.

Включение в список после i-го элемента

J := FREE; индекс свободного элемента

FREE := SPISOK[J].LINK; индекс нового свободного элемента SPISOK[J].INF := C; занести информацию

SPISOK[J].LINK := SPISOK[I].LINK; занести указатель

SPISOK[I].LINK := J; сменить указатель предыдущего элемента

Удаление из списка после i-го элемента

J := SPISOK[I].LINK; нашли индекс удаляемого элемента

C := SPISOK[J].INF; переписали информацию

SPISOK[I].LINK := SPISOK[J].LINK; переписали указатель

теперь добавим перед FREE:

SPISOK[J].LINK := FREE; занесли в указатель индекс

свободного элемента

FREE := J; сменили номер свободного элемента

Операции тоже цикличны и выполняются в обратном порядке (зеркальны).

Однако существуют определенные ограничения, накладываемые на выполнение этих операций:

  1. нужна проверка на переполнение при включении элемента;

  2. нужна проверка на исключение элемента после последнего в списке;

  3. как удалить самый первый элемент?

4) как добавить элемент перед первым элементом?

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]