Смекни!
smekni.com

Последовательные таблицы

Последовательные таблицы.

Будем рассматривать неотсортированные таблицы.

K - количество элементов в таблице

N - длина вектора представления элементов таблицы

Векторное представление:

type элемент = record key ... body ...;

таблица = array [1..N] of элемент

end

key=...

body=...

Время поиска K/2

Списковое представление:

type элемент = record key... body ...;

связь=элемент;

procedure вставить (var table:таблица; var ключ:key; тело:body)

begin

if последний>=N then write(‘нет места’) else begin

последний:=последний+1;

table[последний].key:=ключ;

table[последний].body:=тело;

end;

with table[последний] do

key:=ключ;

body:=тело;

end

end

Предполагаем, что длина ключа и тела одна и та же.

procedure изменить(var table:таблица; var последний:integer)

var i,j:integer;

begin

table[последний+1].key:=ключ;

i:=1;

while not (table[i].key=ключ) do {это условие хотя бы раз выполняется}

i:=i+1;

if i=последний+1 then write(‘нет записи с ‘,ключ) else table[i].тело:=тело

end

Операции вставить и изменить имеют сложность K/2, где К - количество элементов в таблице.

Procedure Исключить(var table:таблица; var последний:integer)

var i:integer

begin {найти такое i: table[i].ключ=ключ и удалить этот элемент из table}

i:=1; | процедура

table[последний+1].ключ:=ключ; |

while table[i].ключ<>ключ do i:=i+1{условие инвариантности цикла}| поиска

if i<=последний then begin

while i<>последний do begin

table[i]:=table[i+1];

i:=i+1

end;

последний:=последний-1;

end else write(‘Такого элемента нет’)

end.

Сложность: К/2 - поиск

К/2 - сдвиг

К/2+К/2=К, то есть сложность линейна

body=...

key=...

type ссылка=звено;

звено=record ключ:key;

тело:body;

связь:ссылка

end;

var таблица:ссылка;

procedure ВСТАВИТЬ(var таблица,последний:ссылка; ключ: key; тело:body)

var элемент:звено;

begin

new(элемент);

элемент.ключ:=ключ;

элемент.тело:=тело;

элемент.связь:=nil;

последний.связь:=элемент;

последний:=элемент;

if таблица=nil then таблица:=элемент else последний.связь:=элемент;

последний:=элемент

end

Сложность не зависит от длины таблицы

procedure изменить (var таблица, последний:ссылка; ключ:key; тело:body)

{найти таблица.ключ = ключ и заменить таблица.тело на тело}

var следующий:ссылка;

begin {поиск элемента с заданным ключом}

if таблица<> nil then begin

new(следующий);

следующий.ключ:=ключ:

следующий.связь:= nil;

последний.связь:=следующий;

следующий:=таблица;

end;

{поиск}

while следующий.ключ<> ключ do следующий:=следующий.связь;

if последний.связь<>следующий then следующий.тело:=тело

else write(‘элемент не найден’);

{нужно уничтожить сгенерированный элемент}

dispose(последний.связь)

end

Сложность К/2

procedure удалить(var таблица, последний: ссылка; ключ: key);

var текущий: ссылка;

{если элемент последний или первый, то рассмотрим отдельно, иначе сдвинем ссылку и освободим память}

if {таблица пуста} then write (‘Таблица пуста’) else

if {в таблице один элемент} then

if {единственный элемент есть искомый} then {сделать таблицу пустой}

else write(‘нет искомого элемента в таблице’)

else write (‘нет искомого элемента в таблице’)

else {поиск в таблице}

new(текущий);

текущий.ключ=ключ;

текущий.связь:=nil;

последний.связь:=текущий;

текущий:=таблица;

while текущий.ключ<> ключ do begin

предок:=текущий;

текущий:=текущий.связь

end

if {первый элемент - искомый} then begin

текущий:=таблица;

таблица:= текущий.связь;

dispose(текущий)

end

if {последний- искомый (текущий=последний)} then begin

последний:=предок;

последний.связь:=nil;

dispose(текущий);

dispose(текущий.связь)

end

else begin

предок.связь:=текущий.связь;

dispose(текущий);

dispose(последний.связь)

end

end

Сложность = сложности поиска по линейному списку К/2

Таблицу нужно формировать так, чтобы наиболее часто встречаемые ключи находились в начале списка. Зная частоту встреча7емости ключей и отсортировав таблицу можно улучшить эффективность.

Сортированные последовательные таблицы.

Типы ключа и тела далее просты.

procedure вставить(var таблица: table; var последний: integer; ключ: key; тело:body)

var i:integer;

begin

if последний = N then write(‘таблица заполнена’) else begin

i:=последний;

{считаем, что все ключи упорядоченны по возрастанию, то есть

I(Kj)=I(Kt)+1

(Kj, Kt)R и не s: (Kj, Ks)R (Ks, Kt)R}

while (i>=1) and (таблица[i].ключ>ключ) do begin

таблица[i+1].ключ:=таблица[i].ключ;

таблица[i+1].тело:=таблица[i].тело;

i:=i-1

end;

таблица[i].тело:=тело;

таблица[i].ключ:=ключ

end

end

Сложность операции вставки для отсортированных таблиц возросла.

Выводы:

1) основная сложность операций в таблице - поиск. Для данной - линейна.

2)векторное представление хорошо, когда операции удаления и вставки относительно редки, а, если же нет, то предпочтение нужно отдавать списковому представлению.

3) Для последовательных таблиц понижение сложности можно достичь за счет использования информации о встречаемости ключей. Операцию поиска можно сократить за счёт сокращения длины путей поиска.