Объектная реализация контейнера на основе комбинированной структуры «Динамический упорядоченный список массивов-стеков»
Автор работы: Пользователь скрыл имя, 13 Декабря 2014 в 10:49, курсовая работа
Описание работы
Цель работы: получение навыков разработки объектных программ, включая создание набора собственных взаимосвязанных классов для объектной реализации специализированного контейнера. Контейнер предназначен для хранения и обработки данных некоторой информационной задачи. Контейнер представляет собой двухуровневую структуру данных, в которой уровни реализуются разными способами – один статически на базе массива (непрерывная реализация), другой – динамически с использованием адресных связей (связная реализация).
Содержание работы
Постановка задачи (цель работы, исходные данные, ожидаемый результат, требования к реализации)……………………………………………………………………………………….2 Теоретическое описание используемых структур данных с алгоритмами реализации основных операций…………………………………………………………….…………….......3 Описание основных понятий и механизмов ООП……………………………………………………………………………………………….9 Описание всех разработанных классов (объектная модель)……………………………...…11 Описание демонстрационного модуля с характеристикой использованных стандартных компонентов……………………………………………………………………………………25 Описание структуры проекта…………………………………………………………………27 Список использованной литературы…………………………………………………………47
Это простейший способ создания
списка. Однако здесь получается, что элементы
стоят в обратном порядке по сравнению
с порядком их добавления в список. В некоторых
задачах это нежелательно, и поэтому новые
элементы должны присоединяться в конце,
а не в начале списка. Хотя конец списка
легко найти простым просмотром, такой
наивный подход приводит к вычислительным
затратам, которых можно избежать, используя
второй указатель, скажем q, который всегда
указывает на последний элемент.
Среди элементарных операций
со списками-вставка и удаление элементов
(частичное изменение списка),а также,
разумеется, проход по списку. Мы сначала
рассмотрим вставку (insertion)
в список.
Предположим, что элемент,
на который ссылается указатель q, нужно
вставить в список после элемента,
на который ссылается указатель р (рис.2).
qànext = pànext; pànext = q;
Рис.2
Если нужна вставка перед указанным
элементом pp, а не после него, то, казалось
бы, возникает затруднение, так как в однонаправленной
цепочке ссылок никакого пути от элемента
к его предшественникам. Однако здесь
может выручить простой прием.
Необходимо вставить новую
компоненту после pp, а потом произвести
обмен значениями между новым элементом
и pp.
q=new NodeDesc;
qq=pp;
pàkey=k;
pànext=q;
Теперь рассмотрим удаление из списка
(list deletion). Нетрудно удалить элемент, стоящий
сразу за pp. Эта операция показана здесь
вместе с повторной вставкой удалённого
элемента в начало другого списка (обозначенного
переменной q). Здесь имеет место циклический
обмен значений трёх указателей.
r = pànext; pànext = rànext; rànext = q; q = r;
Рис.3
Удаление самого элемента,
на который указывает ссылка (а не следующего),
труднее, так как здесь возникает та же
проблема, что и со вставкой: невозможно
просто так перейти назад от элемента
к предшествующему.
Но удаление следующего
элемента после копирования его
значения вперёд – довольно очевидное
и простое решение. Его можно применить,
когда за pp стоит некоторый элемент, то
есть pp не является последним элементом
в списке. Однако необходимо гарантировать,
что нет других переменных, ссылающихся
на удаляемый элемент.
Обратимся теперь к фундаментальной
операции прохода по списку.
Предположим, что для каждого элемента
списка, у которого первый элемент pp, нужно
выполнить некоторую операцию Р(х). Эту
задачу можно выполнить так:
WHILE (список, на который
ссылается р, не пуст)
{
выполнить операцию
Р;
перейти к
следующему элементу;
}
Из определения оператора
while и структуры связей следует, что Р применяется
ко всем элементам списка и ни к каким
другим.
Очень часто используемая
со списками – поиск в списке элемента
с заданным ключом.
В отличие от массивов, поиск
здесь должен быть чисто последовательным.
Поиск прекращается, либо когда элемент
найден, либо когда достигнут конец списка.
Упорядоченные списки
Представленный алгоритм
поиска в линейном списке очень похож
на поиск в массиве или последовательности.
На самом деле последовательность - это
в точности линейный список, для которого
способ связи с последующим элементом
скрыт. Поскольку основные операции для
последовательностей не допускают вставку
новых элементов (разве что в конец) или
удаления (кроме удаления всех элементов),
выбор представления отдается полностью
на откуп проектировщику, и он может выбрать
последовательное размещение в памяти,
располагая последовательные компоненты
в непрерывных областях памяти. Линейные
списки с явными указателями дают больше
гибкости, и поэтому их следует использовать,
когда в такой гибкости есть необходимость.
Если список упорядочен
(скажем, по возрастанию ключей), то поиск
может быть прекращен, как только встретился
первый ключ, больший нового. Упорядочение
списка достигается вставкой новых элементов
в надлежащем месте, а не в начале списка.
При этом упорядоченность получается
практически бесплатно. Это достигается
благодаря легкости вставки элемента
в связный список, то есть благодаря полному
использованию его гибкости. Такой возможности
нет ни при работе с массивами, ни с последовательностями.
(Однако заметим, что даже упорядоченные
списки не дают возможности реализовать
аналог двоичного поиска для массивов.)
Поиск в упорядоченном списке
даёт типичный пример ситуации, когда
новый элемент нужно вставить перед заданным,
в данном случае перед первым элементом,
чей ключ оказался слишком большим. Однако
мы применим здесь новый прием, который
отличается от показанного ранее. Вместо
копирования значений вдоль списка проходят
два указателя: w2 отстает на шаг от w1 и
поэтому указывает на правильное место
вставки, когда w1 обнаруживает слишком
большой ключ. Общий шаг вставки показан
на рис.4.
Рис.4
Организацию данных в связный
список можно рекомендовать, когда число
элементов относительно мало (< 50),
меняется и, более того, когда нет информации
о частоте обращения к ним. Типичный пример
- таблица имен в компиляторах языков программирования.
Каждое объявление добавляет новое имя,
которое удаляется из списка после выхода
из его области видимости. Использование
простых связных списков уместно в приложениях
с относительно короткими программами.
Но даже в этом случае можно добиться значительного
ускорения доступа к данным с помощью
очень простого приёма, который упоминается
здесь прежде всего потому, что он представляет
собой удачную иллюстрацию гибкости связных
списков.
Описание основных
понятий и механизмов ООП
Объекты
По определению будем называть
объектом понятие, абстракцию или любой
предмет с четко очерченными границами,
имеющую смысл в контексте рассматриваемой
прикладной проблемы. Введение объектов
преследует две цели:
понимание прикладной задачи
(проблемы);
введение основы для реализации на компьютере.
Объект - это мыслимая или реальная
сущность, обладающая характерным поведением, отличительными характеристиками
и являющаяся важной в предметной области.
Каждый объект имеет состояние,
обладает некоторым хорошо определенным
поведением и уникальной идентичностью.
Каждый программный объект
имеет некоторый набор данных и некоторый
программный код для обработки этих данных.
Объект: данные “+” код.
Классы
Формально класс - шаблон
поведения объектов определенного типа
с определенными параметрами, определяющими
состояние.
Все объекты одного
и того же класса описываются одинаковыми
наборами атрибутов. Однако объединение
объектов в классы определяется не наборами
атрибутов, а семантикой.
Объединение объектов
в классы позволяет рассмотреть задачу
в более общей постановке. Класс имеет
имя, которое относится ко всем объектам
этого класса. Кроме того, в классе вводятся
имена атрибутов, которые определены для
объектов. В этом смысле описание класса
аналогично описанию типа структуры или
записи, которые широко применяются в процедурном
программировании; при этом каждый объект имеет
тот же смысл, что и экземпляр структуры
(переменная или константа соответствующего
типа).
. Все экземпляры одного
класса (объекты, порожденные от одного
класса)
Имеют один и тот же набор свойств
Общее поведение, одинаково
реагируют на одинаковые сообщения
Инкапсуляция
Инкапсуляция (encapsulation) -
это сокрытие реализации класса и отделение
его внутреннего представления от внешнего
(интерфейса). При использовании объектно-ориентированного подхода
не принято использовать прямой доступ
к свойствам какого-либо класса из методов других
классов. Для доступа к свойствам класса
принято использовать специальные методы этого
класса для получения и изменения его
свойств.
Внутри объекта данные и
методы могут обладать различной степенью
открытости (или доступности).
Открытые члены класса составляют
внешний интерфейс объекта. Эта та функциональность, которая
доступна другим классам. Закрытыми обычно
объявляются все свойства класса, а так
же вспомогательные методы, которые являются
деталями реализации и от которых не должны
зависеть другие части системы.
Агрегация
Агрегация возникает в тех
случаях, когда один объект включает в
себя в качестве составных частей другие
объекты. Агрегация моделирует отношение
типа “часть-целое”.
Обобщение возникает в тех случаях,
когда одно понятие является более общим
по отношению к другим, которые можно считать
его частными случаями или разновидностями.
Обобщение моделирует отношение
типа “общее-частное”.
В свою очередь, объекты
- составные части могут тоже состоять
из своих объектов, т.е. агрегация может
быть многоуровневой. Агрегация позволяет
строить сложные объекты на основе более
простых, используя их свойства и уже реализованные
методы.
Наследование
Наследование (inheritance) - это отношение
между классами, при котором класс использует структуру
или поведение другого(одиночное наследование)
или других (множественное наследование)
классов. Наследование вводит иерархию
"общее/частное", в которой подкласс
наследует от одного или нескольких более
общих суперклассов. Подклассы обычно
дополняют или переопределяют унаследованную
структуру и поведение.
Суть наследования: на основе
уже существующего класса можно создать
один или несколько классов, в которых
можно использовать свойства и методы
исходного класса без их повторного описания
или реализации.
Производный класс включает
в себя:
1)Унаследованные свойства
и методы (их определять не
надо);
2)Новые свойства и методы,
отсутствующие в исходном классе,
за счёт чего дочерний класс
имеет больше свойств и методов
по сравнению с его родителями
и поэтому описывает более
конкретное понятие.
Дополнительно есть возможность
видоизменить (переопределить) некоторые
из унаследованных родительских методов.
Дочерний класс сам может быть
родительским, на его основе можно создавать
свои производные классы и т.д. При этом
возникает многоуровневая иерархия классов:
каждый нижележащий производный класс
включает свойства и методы всех своих
предков. На самом верху иерархии – специальный
корневой класс Object.
Полиморфизм
Полиморфизм (многоформность)
- способность некоторой сущности в разных
ситуациях по-разному проявлять себя.
Основные реализации полиморфизма
в ООП:
1)Полиморфные (виртуальные)
методы;
2) Полиморфные объектные указатели;
Переопределение (overriding) методов
– это возможность объявления в дочерних
классов методов, заголовки которых полностью
совпадают с базовым родительским методом,
но этим методам в дочерних классах даётся
своя программная реализация.
Полное совпадение заголовков
- это совпадение имён методов, количества,
порядка и типов формальных параметров.
Полиморфные методы – это методы,
которые в разных классах некоторой иерархии
имеют одинаковые заголовки, но разную
программную реализацию.
Полиморфизм применительно
к объектным переменным означает возможность
использования одной и той же переменной
для доступа к объектам разных классов.
Если объектная переменная объявлена
с классовым типом BaseClass, то она имеет право
адресовать объекты любых классов, производных
от класса BaseClass.