
- •А. Аппаратное обеспечение компьютеров
- •1. Раздел "Основы теории компьютеров"
- •2. Минимизация булевых функций с помощью диаграмм Вейча.
- •3. Определение и применение базиса при построении произвольных функций алгебры-логики.
- •4. Сложение и вычитание чисел с фиксированной запятой.
- •5. Умножение чисел с плавающей запятой.
- •6. Форматы команд.
- •7. Схема выполнения машинной двухадресной команды типа "Регистр-память" на однопроцессорном компьютере.
- •8. Схема выполнения машинной двухадресной команды типа "Регистр-регистр" на однопроцессорном компьютере.
- •2. Раздел "Архитектура вычислительных систем"
- •1. Архитектура кэш-памяти. Ассоциативное распределение информации в кэш-памяти.
- •2. Архитектура кэш-памяти. Прямое распределение (отображение) информации в кэш-памяти.
- •3. Архитектура векторного блока супер-ЭВМ CYBER-205. Особенности её конвейеров, обеспечивающие механизм "зацепления команд".
- •4. Векторные процессоры: структура аппаратных средств.
- •5. Пять основных архитектур высокопроизводительных ВС, их краткая характеристика, примеры.
- •6. SMP архитектура. Достоинства и недостатки. Область применения, примеры ВС на SMP.
- •7. MPP архитектура. История развития. Основные принципы. Концепция, архитектура и характеристики суперкомпьютера Intel Paragon.
- •8. Кластерная архитектура. Проблема масштабируемости. Примеры.
- •10. Понятие конвейера. "Жадная" стратегия. Понятие MAL в теории конвейера.
- •3. Раздел "Схемотехника ЭВМ"
- •1. Этапы проектирования комбинационных схем на примере дешифратора на 4 выхода: определение, таблица истинности, функция, логическая схема. Увеличение разрядности до 16-ти выходов.
- •2. Этапы проектирования комбинационных схем на примере мультиплексора 4-1: определение, таблица истинности, функция, логическая схема. Увеличение разрядности до 16-1.
- •3. Этапы проектирования комбинационных схем на примере схем сравнения двухразрядных слов: определение, таблица истинности, функция, логическая схема. Схема сравнения четырёхразрядных слов на элементах "Исключающее ИЛИ".
- •6. Синтез многовыходных комбинационных схем. Этапы проектирования в базисе И-НЕ.
- •7. Триггерные схемы: определение, классификация, условные графические обозначения, динамические параметры. Обобщённая структура двухступенчатого триггера, диаграмма его работы, условное графическое обозначение, динамические параметры.
- •8. Синтез двухступенчатого триггера по заданной таблице внешних переходов: таблица истинности, минимизация, схема. Построить временную диаграмму для двух переключений триггера, определить максимальные задержки переключений.
- •9. Счётчики: определение, модуль счётчика, динамические параметры. Примеры суммирующего, вычитающего и реверсивного счётчиков: схемы, временные диаграммы.
- •10. Счётчики: определение, модуль счётчика. Организация цепей переноса: схемы, динамические параметры. (CP)
- •11. Синтез синхронных счётчиков с заданным модулем на заданном типе триггера (DV, JK).
- •Б. Программное обеспечение компьютеров
- •4. Раздел "Алгоритмы и структура данных"
- •1. Понятие логических структур данных. Отображение структуры данных в памяти вектором и списком. Типы списков. Определение, основные операции; особенности их реализации.
- •2. Стек и очередь: определение, основные операции. Особенности выполнений операций при реализации стека и очереди вектором.
- •3. Стек и очередь: определение, основные операции. Особенности выполнения операций при реализации стека и очереди списком.
- •4. Просматриваемая динамическая таблица-вектор: определение, основные операции, особенности их реализации.
- •5. Просматриваемая динамическая таблица-список: определение, основные операции, особенности их реализации.
- •6. Упорядоченная таблица-вектор: определение, основные операции, особенности их реализации.
- •7. Таблица произвольного доступа: определение, основные операции, отображение в памяти. Функция рандомизации, её назначение.
- •9. Перемешанная таблица, использующая перемешивание сложением: определение, основные операции, особенности их реализации.
- •10. Перемешанная таблица, использующая перемешивание сцеплением: определение, основные операции, особенности их реализации.
- •5. Раздел "Базы данных"
- •1. Системы с базами данных. Понятие системы управления базами данных СУБД. Функции СУБД.
- •2. Понятие независимости от данных. Трёхуровневая архитектура ANSI-SPARC. Сравнительная характеристика уровней.
- •3. Модель данных. Назначение моделей данных. Компоненты моделей данных. Классификация моделей данных.
- •5. База данных реляционного типа. Основные понятия и структура реляционной модели. Реляционные языки. Основные правила целостности реляционной модели.
- •6. Реляционная алгебра. Основные операции реляционной алгебры.
- •7. Язык SQL. Операторы определения и манипулирования данными. Выборка данных из таблиц.
- •8. Модель данных "сущность-связь". Основные концепции и способы их представления на диаграммах. Современные методологии построения моделей "сущность-связь".
- •9. Нормализация отношений. Цель нормализации. Приведение к нормальным формам.
- •10. Жизненный цикл приложения баз данных. Основные фазы проектирования базы данных.
- •6. Раздел "Операционные системы"
- •1. Файловые системы современных операционных систем. Интерфейс пользователя для работы с файловой системой.
- •2. Принцип защиты данных в операционных системах. Управление правами доступа к файлам.
- •3. Способы группирования команд в операционных системах. Командные файлы. Программные каналы, конвейеры команд.
- •4. Обзор возможностей командных процессоров (оболочек) операционных систем.
- •5. Принципы организации многозадачного режима в операционных системах.
- •6. Коммуникационные средства многопользовательских операционных систем.
- •7. Генерация, конфигурирование, настройка операционной системы на потребности конкретного пользователя.
- •8. Средства и способы обеспечения многопользовательского режима в операционных системах.
- •9. Понятие процесса. Управление процессами в операционной системе UNIX.
- •10. Понятие программного канала. Средства управления программными каналами.

SP |
|
|
|
|
Stack |
|
|
|
|
|
|
0 |
SP |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
... |
|
|
|
|
|
|
|
n-1 |
Стек пуст
SP Stack
0
1
2
...
n-1
Стек полон
Stack |
SP |
|
|
|
Stack |
||
|
0 |
|
|
|
|
|
0 |
|
1 |
|
|
|
|
|
1 |
|
2 |
|
|
|
|
|
2 |
|
. |
|
|
|
|
|
. |
|
. |
|
|
|
|
|
. |
|
. |
|
|
|
|
|
. |
|
n-1 |
|
|
|
|
|
n-1 |
|
|
|
|
|
|
||
Запись в стек: |
|
|
|
|
Чтение из стека: |
||
int push(тип el){ |
|
|
|
|
int pop(тип &el){ |
||
if(SP < n){ |
|
|
|
|
if( SP > 0){ |
||
stack[SP++]=el; |
|
|
|
|
el = stack[--SP]; |
||
return 1; |
|
|
|
|
return 1; |
||
} else |
|
|
|
|
} |
|
|
return 0; |
|
|
|
|
else |
||
} |
|
|
|
|
|
return 0; |
}
3. Стек и очередь: определение, основные операции. Особенности выполнения операций при реализации стека и очереди списком.
(Стек и очередь - см. билет 2)
Очередь -реализация списком:
При отображении очереди списком можно использовать линейный и циклический список.
Очередь, реализованная линейным односвязным списком: задаётся двумя указателями - на начало и конец очереди.
Возможные ситуации:
1.Очередь пуста. В исходном состоянии оба указателя имеют пустые значения
(NULL).
2.При записи в очередь первого элемента изменяются оба указателя. Первый элемент в данной ситуации становится последним. Последующие операции добавления элементов изменяют только указатель на конец очереди.
3.При чтении из очереди меняется указатель на начало очереди. Когда будет прочитан последний элемент, очередь станет пустой, и оба указателя (на начало и конец очереди) должны иметь пустое значение.

first |
|
first |
Запись в очередь |
|
|
|
|
|
|
||||
|
|
|
|
first |
|
|
|
|
|
|
|||
0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
last |
|
last |
1 |
0 |
|
last |
|
||||||
|
|
|
|
|
|
2 |
0 |
||||||
|
|
|
|
|
|
|
|
||||||
0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
а) Очередь пуста |
|
б) |
Элемент списка: |
|
|
struct Item{ |
|
|
Type info; |
|
|
Item *next; |
|
|
}; |
|
|
Item *first, |
/* |
начало очереди */ |
*last; |
/* |
конец очереди */ |
в)
int putQ(Type el) |
|
|
{ |
= new Item; |
|
Item *ptr |
||
if(!ptr) |
-1; /* |
нет памяти */ |
return |
||
ptr->info |
= el; |
|
ptr->next |
= NULL; |
|
if(!first) |
очередь пуста */ |
|
first = ptr; /* |
||
else |
|
|
last->next = ptr; |
|
|
last = ptr; |
|
|
return 0; |
|
|
} |
|
|
Чтение из очереди
first first first 0
|
|
1 |
|
|
|
|
|
|
|
|
|
|
|
last |
|
|
|
|
|
|
last |
2 |
0 |
|
last |
||
|
|
|
|
|
|
|
|
||||||
|
|
|
|
2 |
0 |
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
0 |
а) |
б) |
Элемент списка: struct Item{
Type info; Item *next;
};
Item *first, /* указатель на начало очереди */ *last; /* указатель на конец очереди */
в) очередь пуста
int getQ(Type &el)
{
Item *ptr = first; if(!first)
return -1; /* очередь пуста */ el = first->info;
first = first->next; delete ptr; if(!first)
last = NULL; return 0;
}
Реализация очереди циклическим односвязным списком:
Достаточно иметь один указатель - на последний элемент (last). Указателем на начало очереди будет являться поле next последнего элемента (первый элемент будет определяться последним элементом).
Возможные ситуации:
1.В исходном состоянии очередь пуста. Указатель на конец очереди имеет пустое значение.
2.При записи нового элемента будет изменяться указатель на конец очереди (будет указывать на записываемый элемент). Так как последний элемент очереди указывает на начало, в поле next записываемого элемента должен быть записан указатель на начало очереди. При записи элемента в пустую очередь, первый элемент является так же и последним, поэтому данный элемент будет указывать сам на себя.
3.При чтении элемента из очереди удаляется первый элемент. Поэтому в последнем элементе (на который указывает конец очереди last) будет меняться значение поле указателя. Когда из очереди будет прочитан последний элемент (перед чтением этот элемент является единственным - и первым, и последним), указатель на конец очереди должен получить пустое значение.

|
|
|
|
|
|
|
|
|
|
|
|
|
Запись в очередь |
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
last |
|
|
|
last |
|
|
|
|
|
|
last |
|
|
|
|
|
2 |
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
а) очередь пуста |
|
|
|
б) |
|
|
|
|
|
|
в) |
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
int putQ(Type el) |
|
|
|
|
|
|
|
|
|
|
||||||
|
Элемент списка: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
struct Item{ |
|
|
|
|
|
|
|
Item *ptr = new Item; |
||||||||||||||||||||
|
|
Type info; |
|
|
|
|
|
|
|
if(!ptr) |
|
|
|
|
/* нет памяти */ |
||||||||||||||
}; |
Item *next; |
|
|
return -1; |
|
|
|
||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
ptr->info = el; |
|
|
|
|
|
|
|
|
|
|
||||||||
|
Item *last; /* |
|
|
|
|
|
|
|
if(!last) |
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
конец очереди */ |
|
|
ptr->next = ptr; /* очередь пуста */ |
|||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
else{ |
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ptr->next = last->next; |
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
last->next = ptr; |
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
last = ptr; |
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Чтение из очереди |
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
last |
|
2 |
|
|
|
|
last |
|
2 |
|
|
|
|
last |
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0 |
|
|
|
|
|
а) |
|
|
|
|
|
|
|
|
б) |
|
|
|
|
|
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
в) очередь пуста |
|||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
int getQ(Type &el) |
|
|
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
Элемент списка: |
{ |
Item *ptr; |
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
struct Item{ |
|
|
|
|
|
|
|
if(!last) |
|
/* |
|
очередь пуста */ |
|||||||||||||||||
|
Type info; |
|
|
|
|
|
|
|
|
return -1; |
|
|
|||||||||||||||||
}; |
Item *next; |
|
|
|
|
|
|
|
ptr = last->next; /* |
начало очереди */ |
|||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
el = ptr->info; |
|
|
|
|
|
|
|
|
|
|
|||||||
Item *last; /* конец очереди */ |
if(last == ptr) |
/* |
|
прочитан последний элемент */ |
|||||||||||||||||||||||||
|
last = NULL; |
|
else
last->next = ptr->next; delete ptr;
return 0;
}
Стек -реализация списком:
При отображении стека списком используется линейный односвязный список.
Возможные состояния:
1.В исходном состоянии, когда стек пуст, вершина стека - указатель имеет пустое значение SP=NULL. Создаваемый элемент включается в начало списка.
2.Ситуация "стек полон" достигается, когда создание нового элемента заканчивается неудачей (функция выделения памяти malloc()или оператор языка С++ выделения памяти new возвращают значение NULL, что свидетельствует об ошибке)
3.При чтении из стека, реализованного списком, первый элемент исключается из списка. Информация из элемента списка передаётся как результат операции чтения.

struct Item{ |
Исходное состояние - |
|
|
|
SP |
|
||||||||||||||||
|
тип info; |
стек пуст: |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
Item *next; |
Item *SP = NULL; |
|
|
|
|
0 |
|
|
|
|
|
||||||||||
} ; |
|
|
|
|
|
|
|
|
|
SP |
|
|
|
|
|
|
|
|
|
|
|
|
SP |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
0 |
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
Новый элемент |
|
|
|
|
|
а) До чтения |
|||||||||||||||
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
а) До записи |
|
|
SP |
|
|
|
|
|
|
|
|
|
|
|
|
||||
SP |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
||
|
|
|
|
|
|
|
1 |
0 |
|
|
|
|
|
|
|
1 |
0 |
|||||
|
3 |
|
|
|
|
|
|
|
|
3 |
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Элемент прочитан |
|
||||||||||
Элемент записан |
|
|
|
|
||||||||||||||||||
|
|
|
б) После записи |
|
|
|
|
|
б) После чтения |
|
||||||||||||
Запись в стек: |
|
|
|
|
Чтение из стека: |
|
||||||||||||||||
int push(тип el){ |
|
|
|
|
int pop(тип &el){ |
|
||||||||||||||||
|
Item *tmp = new Item; |
|
|
|
|
|
Item *tmp = SP; |
|
||||||||||||||
|
if(!tmp) |
|
|
|
|
|
if(!top) |
|
||||||||||||||
|
return 0; |
|
|
|
|
|
|
return 0; |
|
|||||||||||||
|
tmp->info = el; |
|
|
|
|
|
SP = SP->next; |
|
||||||||||||||
|
tmp->next = SP; |
|
|
|
|
|
el = tmp->info; |
|
||||||||||||||
|
SP = tmp; |
|
|
|
|
|
delete tmp; |
|
||||||||||||||
} |
return 1; |
|
|
|
} |
return 1; |
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4. Просматриваемая динамическая таблица-вектор: определение, основные операции, особенности их реализации.
(Алгоритмы и структуры данных, лекция 17.03.2004)
Таблица:
Таблица представляет собой совокупность элементов, имеющих 2 поля: информационное поле, позволяющее хранить нужную информацию; и поле ключа, позволяющее организовывать доступ к информации.
Ключ Информация
Ключ - уникален для всех записей таблицы. Может быть достаточно сложным и иметь внутреннюю структуру (например, идентифицирующая информация + номер версии). Ключ однозначно идентифицирует информацию элемента таблицы.
Операции с таблицей:
1.Добавление элемента. Включение нового элемента в таблицу (при этом, чтобы сохранить уникальность ключа, необходимо убедиться, что в таблице дубликатов ключа нет)
2.Доступ к элементу. Поиск (самая главная операция в таблицах!)
3.Удаление элемента из таблицы (при удалении - так же требуется сначала найти удаляемый элемент).
Критерии классификации таблиц:
1.Тип операций (способ доступа):
1.1.статические (операции включения/удаления не разрешены; определена только операция поиска).
1.2.динамические (определены все операции с таблицей).
2.Организация операции поиска (способ организации таблицы):
2.1.просматриваемые
2.2.упорядоченные
2.3.таблицы с вычисляемым входом
2.3.1.таблицы произвольного доступа
2.3.2.хэш-таблицы (перемешанные)
Таблицы могут быть представлены (в памяти):
1.вектором
2.списком
3.семейством списков.
Просматриваемая таблица:
Просматриваемая таблица - таблица, в которой не устанавливаются никакие правила по отношению к размещению ключей в таблице.
Особенности:
1.Наиболее легко реализуется
2.Самые медленные таблицы. Целесообразно использовать только для небольших таблиц (несколько десятков элементов).
Обычно просматриваемые таблицы бывают динамические.
Просматриваемая динамическая таблица-вектор Операции.
1.Включение элемента. Поскольку разрешена операция включения, необходимо иметь информацию о наличии в таблице свободных позиций. При наличии нескольких свободных позиций, требуется решить, в какую именно будет добавлен элемент.
2.Удаление элемента. Для фиксации свободных и занятых элементов таблицы, в элемент таблицы включают дополнительное поле 0/1 - поле занятости.
3.Поиск. На реализацию поиска может повлиять наличие в таблице свободных элементов (следует учитывать, свободен элемент или занят).
4."Сборка мусора" (garbage)
Проблемы:
1.Как искать?
2.Как учитывать переполнение вектора?(операция "сборка мусора")
Рекомендации:
1.Просматриваемые таблицы небольшие по размеру
2.Помечать удалённые элементы + периодически выполнять "сборку мусора"
Возможные ситуации:
1.В исходном состоянии таблица пуста и все элементы помечены как свободные (в поле занятости =0).
2.При включении нового элемента в таблицу, требуется найти подходящий свободный элемент. Критерием для выбора может служить L - длина доступа (количество элементов таблицы, которые необходимо просмотреть, прежде чем будет найдена свободная позиция). Можно обеспечить L=1, если все операции включения выполнять в конец таблицы (и ввести переменную int n, которая определяет первый свободный элемент в конце таблицы). В исходном состоянии n=0. Каждая операция добавления увеличивает n на 1.
3.При удалении элемента достаточно установить "0" в поле занятости. Не стоит при удалении элемента из середины таблицы перемещать информацию из конца таблицы в освободившуюся позицию, т.к. это может привести к увеличению времени выполнения операции (поэтому n при удалении не меняет своего значения).
4.Операция сборки мусора. После включения/удавления с течение времени возникает ситуация, когда свободных позиций в конце таблицы нет (n = M) в то время, как в
середине таблицы есть множество элементов, помеченных как свободные. В этом случае перед включением нового элемента, необходимо реорганизовать таблицу, собрав все свободные элементы в конце таблицы и изменив её текущий размер n. В зависимости от того, насколько часто прикладная программа выполняет операции включения/удаления, может оказаться целесообразным выполнить операцию сборки мусора, чтобы последующие операции включения не требовали дополнительных расходов. Замечание: можно включать новый элемент в первую найденную свободную позицию (исключив операцию сборки мусора), но увеличив время выполнения операции включения.
Примеры:
Конкретная реализация вспомогательных функций (удаление информации и создание копии данных) зависит от типа информации, включаемой в таблицу (тип Type), и определяется разработчиком соответствующего приложения.
/* Максимальный размер таблицы */
/* поле занятости */ /* ключ */
/* информация */
};
Item table[M]; /* Объявление таблицы как внешней (вне функций) приводит к тому, что все элементы инициализируются нулем; поэтому можно не устанавливать явно
значения 0 в поле busy всех элементов при создании таблицы */ int n = 0;
/* поиск элемента в таблице */ int search(int k)
{
int i;
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; |
/* "удаление" элемента */ |
||
delInfo(table[I].info); |
|
|
|
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; |
|