Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[67]

Рис. 11.4 Список Г, использующий фиктивный элемент пг1[Г] (тёмно-серый прямоугольник). Вместо head[L\ используем nexi[nil[L\]. (а) Пустой список, (б) Список рис. 11.3а (элемент с ключом 9 - голова, 1 - хвост), (в) Тот же список после процедуры List-Insert(L, х), если fceg/fa;] = 25. (г) После удаления элемента с ключом 1. Новый хвост имеет ключ 4.

у хвоста списка занесём указатели на nil[L] (рис. 11.4). При этом next[ni\L]\ - указатель на голову списка, так что атрибут head[L] становится лишним. Пустой список L теперь будет кольцом, в котором nil[L] - единственный элемент.

В процедуре List-Search нужно лишь заменить nil на nil[L] и head[L] на next[nil[L]]:

List-Search(L, k)

1х <- next[nil[L]]

2while x ф nil[L] and key[x] ф k

3do x <- next[x]

4return x

Для удаления элемента годится процедура List-Delete, приведённая выше. Наконец, добавлять элемент к списку можно так:

List-Insert(L, х)

1next[x] <- next[nil[L]]

2prev[next[nil[L]]] <- х

3next[nil[L]] <- х

4prev[x] <- nil[L]

Пример работы процедур List-Insert и List-Delete показан на рис. 11.4.

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

Не следует применять фиктивные элементы без нужды. Если алгоритм использует много коротких списков, использование фик-


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

Упражнения

11.2-1 Можно ли добавить элемент в множество, представленное односторонне связанным списком, за время 0(1)? Тот же вопрос для удаления элемента.

11.2-2 Реализуйте стек на базе односторонне связанного списка. Операции Push и Pop должны выполняться за время 0(1).

11.2-3 Реализуйте очередь на базе односторонне связанного списка. Операции Enqueue и Dequeue должны выполняться за время 0(1).

11.2-4 Реализуйте словарные операции Insert, Delete и Search для свёрнутого в кольцо односторонне связанного списка. Каково время работы ваших процедур?

11.2-5 Операция Union (объединение) получает на входе два непересекающихся множества и возвращает их объединение (сами исходные множества при этом пропадают). Реализуйте эту операцию так, чтобы она работала за время 0(1), представляя множества списками подходящего типа.

11.2-6 Напишите процедуру, которая сливает два односторонне связанных упорядоченных списка в один (также упорядоченный), не используя фиктивных элементов. Затем сделайте это, используя фиктивный элемент с ключом оо (добавляемый в конец списков). Какая из двух программ проще?

11.2-7 Напишите нерекурсивную процедуру, которая за время О (га) переставляет элементы односторонне связанного списка в обратном порядке. Объём дополнительной (помимо необходимой для хранения исходного списка) памяти должен быть 0(1).

11.2-8* Есть способ сэкономить место при реализации двусторон-не связанного списка, сжав два указателя next и prev в одно значение гар[ж]. Будем считать, что все указатели суть /г-битные числа и указателю nil соответствует число нуль. Определим пр[х] по формуле пр[х] = next[x] XORprev[x], где XOR - побитовое сложение по модулю 2 (исключающее ИЛИ). Не забудьте указать, каким образом хранится информация о голове списка. Как реализовать операции Search, Insert и Delete? Объясните, как переставить такой список в обратном порядке за время 0(1).


Рис. 11.5 Список рис. 11.3а, представленный с помощью тройки массивов (key, next, prev). Каждому элементу списка соответствует светло-серый столбик. В верхней строчке выписаны порядковые номера, играющие роль указателей; действие указателей показано стрелками. Значение переменной Г - указатель на голову списка.

11.3. Реализация указателей и записей с несколькими полями

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

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

Массив, составленный из записей, можно заменить несколькими массивами (по одному на каждое поле записи). Например, на рис. 11.5 показано, как представить в виде трёх массивов тот же список, что и на рис. 11.3а: в массиве key хранятся ключи, а в массивах next и prev - указатели. Каждому элементу списка соответствует тройка (key[x], next[x\, prev[x]) для некоторого индекса х. Роль указателя на этот элемент играет число х. В качестве NIL можно использовать число, не являющееся индексом никакого элемента массивов (например, 0 или -1). На рис. 11.3а запись с ключом 4 стоит в списке сразу после записи с ключом 16; и действительно, число 16 стоит в массиве key на месте с номером 5, число 4 - на месте номер 2, и имеем next[5] = 2, а также prev[2] = 5.

В наших программах обозначение типа кеу[х] может пониматься двояко: и как элемент массива key с индексом х, и как поле key записи с адресом х (в зависимости от возможностей языка программирования полезно то или другое понимание).

Представление с помощью одного массива

Вместо нескольких массивов можно использовать один, размещая в нём различные поля одного объекта рядом. Так обычно поступает компилятор: если в программе используется массив эле-



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196] [стр.197] [стр.198] [стр.199] [стр.200] [стр.201] [стр.202] [стр.203] [стр.204] [стр.205] [стр.206] [стр.207] [стр.208] [стр.209] [стр.210] [стр.211] [стр.212] [стр.213] [стр.214] [стр.215] [стр.216] [стр.217] [стр.218] [стр.219] [стр.220] [стр.221] [стр.222] [стр.223] [стр.224] [стр.225] [стр.226] [стр.227] [стр.228] [стр.229] [стр.230] [стр.231] [стр.232] [стр.233] [стр.234] [стр.235] [стр.236] [стр.237] [стр.238] [стр.239] [стр.240] [стр.241] [стр.242] [стр.243] [стр.244] [стр.245] [стр.246] [стр.247] [стр.248] [стр.249] [стр.250] [стр.251] [стр.252] [стр.253] [стр.254] [стр.255] [стр.256] [стр.257] [стр.258] [стр.259] [стр.260] [стр.261] [стр.262] [стр.263] [стр.264] [стр.265] [стр.266] [стр.267] [стр.268] [стр.269] [стр.270] [стр.271] [стр.272] [стр.273] [стр.274] [стр.275] [стр.276] [стр.277] [стр.278] [стр.279] [стр.280] [стр.281] [стр.282] [стр.283] [стр.284] [стр.285] [стр.286] [стр.287] [стр.288] [стр.289] [стр.290] [стр.291] [стр.292] [стр.293] [стр.294]