Список
Для начала разработаем код, реализующий применительно к односвязным спискам основные из обозначенных нами выше операций со связанными списками. Односвязные списки часто формируют с головы, то есть включение новых элементов производится в голову списка.
Первая проблема – выделение памяти для списка. Это можно делать либо статическим способом, зарезервировав место в сегменте данных, либо динамически, то есть так, как мы это делали выше при реализации операций со стеками и очередями. Недостатки первого способа очевидны, хотя в реализации он очень прост. Гораздо интереснее и предпочтительнее второй способ, который предполагает использование кучи для хранения связанного списка. Для придания большей реалистичности изложению рассмотрим простую задачу: ввести с клавиатуры символьную строку, ограниченную символом "." (точка), и распечатать ее в обратном порядке.
:prgl5_102.asm – реализация программы инвертирования строки с односвязными списками :Вход: символьная строка с клавиатуры. :Выход: вывод на экран инвертированной обратной строки. ;……… itemjist struc:элемент списка next dd 0:адрес следующего элемента info db 0 содержательная часть (в нашем случае – символ) ends .data mas db 80 dup С '):в эту строку вводим mas revdb 80 dup (' '):из этой строки выводим len mas rev=$-mas rev mesl db 'Введите строку символов (до 80) для инвертирования (с точкой на конце):' len_mesl=$-mesl .code списание макрокоманд работы со связанным списком; createjist macro descr:REQ.head:REQ : создание списка – формирование головы списка и первого элемента ;……… endm addjist macro descr:REQ.head:REQ.H_Head:REQ добавление элемента в связанный список endm createjtem macro descr:REQ.H_Head:REQ ;создание элемента в куче для последующего добавления в связанный список ¦……… endm start proc near:точка входа в программу: :вывод строки текста – приглашения на ввод строки для инвертирования!……… :вводим строку в mas :……… ;создаем связанный список createjist itemJist.HeadJist:первый элемент обрабатываем отдельно leaesi.mas moval.[esi] cmp al."." je rev_out mov [ebx].info.al :вводим остальные символы строки с клавиатуры до тех пор. пока не встретится "." cycl: incesi mov al.[esi] cmp al,"." je rev_out addj i st i temj i st. HeadJ i st. Hand_Head mov [ebx].info.al jmp cycl :вывод строки в обратном порядке rev_out: mov esi.offset mas_rev mov ebx,HeadJist cycl2: mov al.[ebx].info mov [esil.al inc esi mov ebx.[ebx].next cmpebx.Offffffffh jne cycl2; выводим инвертированную строку на экран
Недостаток такого способа построения списка – в порядке включения элементов. Хорошо видно, что он обратный порядку поступления элементов. Для исправления данной ситуации можно, конечно, ввести еще один указатель на последний элемент списка. Есть и другой вариант – организация двусвязного списка. Уделим теперь внимание другим операциям с односвязным списком.