Матрицы со случайным расположением элементов
К данному типу относятся матрицы, у которых местоположение элементов со значениями, отличными от фонового, не могут быть математически описаны, то есть в их расположении нет какой-либо закономерности.
Пусть есть матрица A размерности 57, в которой из 35 элементов только 10 отличны от нуля:
0 | 0 | 6 | 0 | 9 | 0 | 0 |
2 | 0 | 0 | 7 | 8 | 0 | 4 |
10 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 12 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 3 | 0 | 0 | 5 |
Один из основных способов хранения подобных разреженных матриц заключается в запоминании ненулевых элементов в одномерном массиве записей с идентификацией каждого элемента массива индексами строки и столбца матрицы (см. Рисунок 6). Такой способ хранения называется последовательным представлением разреженных матриц.
Рисунок 6. Последовательное представление разреженных матриц
Доступ к элементу матрицы A с индексами i и j выполняется выборкой индекса i из поля Row, индекса j из поля Colum и значения элемента из поля Value. Следует отметить, что элементы матрицы обязательно запоминаются в порядке возрастания номеров строк для ускорения поиска.
Такое представление матрицы A сокращает используемый объем памяти. Для больших матриц экономия памяти является очень актуальной проблемой.
Однако последовательное представление разреженных матриц имеет определенные недостатки. Так включение и исключение новых элементов матрицы вызывает необходимость перемещения большого числа существующих элементов. Если включение новых элементов и их исключение осуществляется часто, то можно использовать описываемый ниже метод связанных структур.
Метод связанных структур переводит статическую структуру матрицы в динамическую. Эта динамическая структура реализована в виде циклических списков.
Для такого представления разреженных матриц требуется следующая структура элемента списка:
type
PElement = ^TypeElement; {указатель на тип элемента}
TypeElement = record {тип элемента списка}
Left: PElement; {указатель на пред. элемент в строке}
Up: PElement; {указатель на пред. элемент в столбце}
Value: TypeData; {значение элемента матрицы}
Row: integer; {индекс строки матрицы}
Colum: integer; {индекс столбца матрицы}
end;
Рисунок 7 показывает связанную структуру для разреженной матрицы A.
Рисунок 7. Представление разреженных матриц в виде связанных структур
Циклический список представляет отдельную строку или столбец. Список столбца может содержать общие элементы с одним или более списком строки. Для того чтобы обеспечить использование более эффективных алгоритмов включения и исключения элементов, все списки строк и столбцов имеют головные элементы. Головной элемент каждого списка строки содержит ноль в поле Colum. Аналогично, каждый головной элемент в списке столбца имеет ноль в поле Row. Строка или столбец, содержащие только нулевые элементы, представлены головными вершинами, у которых поле Left или Up указывает само на себя.
Может показаться странным, что указатели в этой многосвязной структуре направлены вверх и влево, вследствие чего при сканировании циклического списка элементы матрицы встречаются в порядке убывания номеров строк и столбцов. Такой метод представления используется для упрощения включения новых элементов в структуру. Предполагается, что новые элементы, которые должны быть добавлены к матрице, обычно располагаются в порядке убывания индексов строк и индексов столбцов. Если это так, то новый элемент всегда добавляется после головного и не требуется никакого просмотра списка.
-
Стек
Стек – это структура данных, в которой новый элемент всегда записывается в ее начало (вершину) и очередной читаемый элемент также всегда выбирается из ее начала. Здесь используется принцип «последним пришел – первым вышел» (LIFO: Last Input – First Output).
Стек можно реализовывать как статическую структуру данных в виде одномерного массива, а можно как динамическую структуру – в виде линейного списка.
При реализации стека в виде статического массива необходимо резервировать массив, длина которого равна максимально возможной глубине стека, что приводит к неэффективному использованию памяти. Одновременно, работать с такой реализацией проще и быстрее.
При такой реализации дно стека будет располагаться в первом элементе массива, а рост стека будет осуществляться в сторону увеличения индексов. Одновременно, необходимо отдельно хранить значение индекса элемента массива, являющегося вершиной стека.
Можно обойтись без отдельного хранения индекса, если в качестве вершины стека всегда использовать первый элемент массива, но в этом случае, при записи или чтении из стека, необходимо будет осуществлять сдвиг всех остальных элементов, что приводит к дополнительным затратам вычислительных ресурсов.
Стек как динамическую структуру данных легко организовать на основе линейного списка. Поскольку работа всегда идет с заголовком стека, то есть не требуется осуществлять просмотр элементов, удалению и вставку элементов в середину или конец списка, то достаточно использовать экономичный по памяти линейный однонаправленный список. Для такого списка достаточно хранить указатель вершины стека, который указывает на первый элемент списка. Если стек пуст, то списка не существует и указатель принимает значение nil.
Рисунок 8. Стек и его организация
Поскольку стек, по своей сути, является структурой с изменяемым количеством элементов, то основное внимание уделим динамической реализации стека. Как уже говорилось выше, для такой реализации целесообразно использовать линейный однонаправленный список. Поэтому, при описании динамической реализации будем использовать определения и операции, приведенные в п. 2.2.6.1.
Описание элементов стека аналогично описанию элементов линейного однонаправленного списка, где DataType является типом элементов стека. Поэтому здесь приводить его не будем.
Основные операции, производимые со стеком:
-
записать (положить в стек);
-
прочитать (снять со стека);
-
очистить стек;
-
проверка пустоты стека.
Реализацию этих операций приведем в виде соответствующих процедур, которые, в свою очередь, используют процедуры операций с линейным однонаправленным списком.
procedure PushStack(NewElem: TypeData;
var ptrStack: PElement);
{Запись элемента в стек (положить в стек)}
begin
InsFirst_LineSingleList(NewElem, ptrStack);
end;
procedure PopStack(var NewElem: TypeData,
ptrStack: PElement);
{Чтение элемента из стека (снять со стека)}
begin
if ptrStack <> nil then begin
NewElem := ptrStack^.Data;
Del_LineSingleList(ptrStack, ptrStack); {удаляем вершину}
end;
end;
procedure ClearStack(var ptrStack: PElement);
{Очистка стека}
begin
while ptrStack <> nil do
Del_LineSingleList(ptrStack, ptrStack); {удаляем вершину}
end;
function EmptyStack(var ptrStack: PElement): boolean;
{Проверка пустоты стека}
begin
if ptrStack = nil then EmptyStack := true
else EmptyStack := false;
end;
- Содержание
- Основные сведения
- Понятия алгоритма и структуры данных
- Анализ сложности и эффективности алгоритмов и структур данных
- Структуры данных
- Элементарные данные
- Данные числовых типов
- Данные целочисленного типа
- Данные вещественного типа
- Операции над данными числовых типов
- Данные символьного типа
- Данные логического типа
- Данные типа указатель
- Линейные структуры данных
- Множество
- Линейные списки
- Линейный однонаправленный список
- Линейный двунаправленный список
- Циклические списки
- Циклический однонаправленный список
- Циклический двунаправленный список
- Разреженные матрицы
- Матрицы с математическим описанием местоположения элементов
- Матрицы со случайным расположением элементов
- Очередь
- Нелинейные структуры данных
- Мультисписки
- Слоеные списки
- Спецификация
- Реализация
- Деревья
- Общие сведения
- Обходы деревьев
- Спецификация двоичных деревьев
- Реализация
- Основные операции
- Организация
- Представление файлов b-деревьями
- Основные операции
- Общая оценка b-деревьев
- Алгоритмы обработки данных
- Методы разработки алгоритмов
- Метод декомпозиции
- Динамическое программирование
- Поиск с возвратом
- Метод ветвей и границ
- Метод альфа-бета отсечения
- Локальные и глобальные оптимальные решения
- Алгоритмы поиска
- Поиск в линейных структурах
- Последовательный (линейный) поиск
- Бинарный поиск
- Хеширование данных
- Функция хеширования
- Открытое хеширование
- Закрытое хеширование
- Реструктуризация хеш-таблиц
- Поиск по вторичным ключам
- Инвертированные индексы
- Битовые карты
- Использование деревьев в задачах поиска
- Упорядоченные деревья поиска
- Случайные деревья поиска
- Оптимальные деревья поиска
- Сбалансированные по высоте деревья поиска
- Поиск в тексте
- Прямой поиск
- Алгоритм Кнута, Мориса и Пратта
- Алгоритм Боуера и Мура
- Алгоритмы кодирования (сжатия) данных
- Общие сведения
- Метод Хаффмана. Оптимальные префиксные коды
- Кодовые деревья
- Алгоритмы сортировки
- Основные сведения. Внутренняя и внешняя сортировка
- Алгоритмы внутренней сортировки
- Сортировка подсчетом
- Сортировка простым включением
- Сортировка методом Шелла
- Сортировка простым извлечением.
- Древесная сортировка
- Сортировка методом пузырька
- Быстрая сортировка (Хоара)
- Сортировка слиянием
- Сортировка распределением
- Сравнение алгоритмов внутренней сортировки
- Алгоритмы внешней сортировки
- Алгоритмы на графах
- Алгоритм определения циклов
- Алгоритмы обхода графа
- Поиск в глубину
- Поиск в ширину (Волновой алгоритм)
- Нахождение кратчайшего пути
- Алгоритм Дейкстры
- Алгоритм Флойда
- Переборные алгоритмы
- Нахождение минимального остовного дерева
- Алгоритм Прима
- Алгоритм Крускала
- 190000, Санкт-Петербург, ул. Б. Морская, 67