Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
К9-12В. Вопросы и ответы к ГОСам 2013 / Программирование на языке высокого уровня / 04. Просматриваемая динамическая таблица - вектор. Определение, основные операции и особенности их реализации.docx
Скачиваний:
115
Добавлен:
10.05.2014
Размер:
44.18 Кб
Скачать

Статическая просматриваемая таблица-вектор

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

int search(int k){

int i;

for(i = 0; i< M && table[i].key != k; i++)

;

return (i<M ? i : -1);

}

Динамическая просматриваемая таблица-вектор

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

Прежде всего, поскольку разрешена операция включения, нужно иметь информацию о наличии в таблице свободных позиций; кроме того, при наличии в таблице нескольких свободных позиций необходимо решить, в какую именно будет включаться новый элемент. Свободные позиции в такой таблице могут появляться, в том числе, и в результате выполнения операций удаления элементов. Наличие в таблице свободных элементов может повлиять на реализацию всех операций с таблицей, в том числе, и на реализацию алгоритма поиска.

Рассмотрим различные способы реализации операций с таблицей.

Способ 1.Для фиксации в таблице свободных и занятых элементов полезно реорганизовать элемент таблицы, включив в него дополнительное (служебное) поле 1/0 – поле занятости (рис.II-35): значение 1 в этом поле означает, что элемент занят, значение 0 – что элемент свободен.

1/0

ключ

информация

Рис. II‑1.

В исходном состоянии таблица пуста, и все элементы таблицы помечены как свободные. При включении нового элемента в таблицу нужно найти подходящий свободный элемент. Критерием для выбора может служить длина доступа L(количество элементов таблицы, которое необходимо просмотреть, прежде чем будет найдена свободная позиция; в какой-то степени длина доступа аналогична длине поиска). Можно обеспечитьL= 1, если все операции включения выполнять в конец таблицы и использовать специальную переменную (например,int n;), которая определяет первый свободный элемент в конце таблицы. В исходном состоянииn=0; каждая операция включения нового элемента увеличивает значениеn. Если при выполнении операции включения в таблицу нового элемента свободная позиция не будет найдена, операция завершается отказом.

Пусть, например, выполнялись подряд несколько операций включения элементов в таблицу (последовательность элементов 25, 13, 47, 18, 33)

При удалении элементав найденном элементе таблицы достаточно установить в 0 поле занятости; можно не модифицировать значения других полей таблицы. Пусть, например, элементы удалялись в следующем порядке: 33, 18, 13.

Таким образом, после выполнения указанных выше операций включения и удаления, состояние таблицы может иметь вид, приведенный на рис. II-36. Если после этих операций будет выполняться, например, операция поиска элемента с ключом 13, она должна завершиться отказом (элемент был удален). Следовательно, при выполнении поиска элемента в таблице следует учитывать, свободен очередной элемент или занят.

1/0

ключ

информация

1

25

...

0

13

...

1

47

...

0

18

...

0

33

...

Рис. II‑2.

Такая реализация операции удаления влияет также и на операцию включения в таблицу нового элемента. Если новый элемент включается всегда в конец таблицы, с течением времени может возникнуть ситуация, когда в конце таблицы свободных позиций нет (т.е. n = M), в то время как в середине таблицы есть много элементов, помеченных как свободные. В таких ситуациях, прежде чем можно будет выполнить очередную операцию включения нового элемента в таблицу, следует ее реорганизовать, собрав все свободные элементы в конце таблицы и изменив текущий размер таблицы (n). Такая операция получила название "сборки мусора".

Поскольку операция сборки мусора приводит к перемещению информации в таблице, она является достаточно медленной. Данную операцию можно выполнять, например, вместе с операцией включения нового элемента в таблицу: если оказалось, что в конце таблицы нет свободного элемента, тогда выполняется операция сборки мусора. Если и после выполнения данной операции в конце таблицы нет свободного элемента, значит, таблица полна, и операция включения нового элемента завершается отказом.

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

Способ 2.Поле занятости не используется и не включается в структуру элемента таблицы. В этом случае алгоритм поиска реализуется без каких-либо изменений. Включение нового элемента выполняется всегда в конец таблицы, что приводит к увеличению значенияn. При удалении элемента из таблицы в освободившуюся позицию переписывается последний элемент таблицы, после чего значение переменнойnуменьшается.

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

Тексты функций для выполнения операций включения, удаления, поиска элементов в таблице и "сборки мусора" приводятся ниже и в файле Programs/tab1vec.cpp.

const int M = 20; // Максимальный размер таблицы

struct Item{

int busy; //поле занятости

int key; //ключ

Type info; // информация

};

Item table[M]; /* Объявление таблицы как внешней (вне функций) приводит к тому, что все элементы инициализируются нулем; поэтому можно не устанавливать явно значения 0 в полеbusy всех элементов при создании таблицы */

int n = 0; // текущий размер таблицы

/* поиск элемента в таблице */

int search(int k)

{

inti;

for(i = 0; i< n; i++)

if(table[i].busy && table[i].key == k)

return i; /* элемент найден – он занят и имеет искомый ключ */

return -1; /* элемент не найден */

}

/* удаление элемента*/

int del(int k)

{

int l;

if((l = search(k)) < 0)

return-1; /* указанного элемента в таблице нет */

table[l].busy = 0; /* "удаление" элемента */

return 0;

}

/* "сборка мусора" */

int garbage()

{

int i, cur = n;

n = 0;

for(i = 0; i< cur; i++)

if(table[i].busy){ /* элемент занят */

if(i != n) /* элемент должен быть перемещен */

table[n] = table[i]; /* перемещение элемента */

n++;

}

return n== M ? -1 : 0; /* в таблице нет свободного места */

}

/* включение нового элемента в таблицу */

int insert(int k, Type in)

{

if(search(k) >= 0)

return -1; /* в таблице есть элемент с заданным ключом */

if(n== M) /* в конце таблицы нет свободной позиции */

if(garbage() < 0) /* "сборка мусора" */

return-2; /* в таблице нет свободной позиции */

/* включение нового элемента в таблицу */

table[n].busy = 1;

table[n].key = k;

table[n++].info = in;

return 0;

}

Соседние файлы в папке Программирование на языке высокого уровня