Новинки компьютерных книг ->> Структуры данных и другие объекты в С++
Информационный Канал Subscribe.Ru |
Структуры данных и другие объекты в С++2-е изданиеМайкл Мейн, Уолтер Савитч
ПредисловиеЭта книга представляет собой учебник для студентов второго курса, изучающих компьютерные науки. Основное внимание в ней уделяется спецификации, проектированию, реализации, а также использованию основных типов данных. Кроме того, освещаются вопросы, связанные с применением абстрактных типов данных, излагаются основы объектно-ориентированного программирования, описывается сортировка, а также проводится анализ быстродействия алгоритмов. Предполагается, что студенты уже прослушали вводный курс по компьютерным наукам и программированию, однако некоторые темы (например, рекурсия и указатели) рассматриваются повторно. В основном, в книге описывается язык С++, однако изучение классов языка С++ начинается с азов, поэтому учебник будет понятен и студентам, знающим только язык С. Судя по нашему опыту, таким студентам достаточно кратко описать способы ввода и вывода на языке С++ (как это сделано в приложении 6) и методы передачи параметров функций (см. главу 2). Освоив способы ввода и вывода на языке С++ и работу с параметрами (и, возможно, преодолев небольшой страх), программисты, владеющие языком С, могут смело переходить к разработке классов и овладению другими объектно-ориентированными свойствами языка С++. Книгу можно читать по-разному, в зависимости от опытности читателя. Читатель с обычной подготовкой может пропустить некоторые главы, предназначенные для искушенных студентов. Второе издание: новый материал и дополнительная поддержка в ИнтернетТипы данных и темы изложены в том же порядке, что и в первом издании. Преподаватели, использовавшие его в своей практике, могут продолжать преподавание в том же стиле, учтя следующие изменения, связанные с введением в 1998 году нового стандарта ANSI/ISO C++ Standard. www.cs.colorado.edu/~main/dsoc.html
Этапы описания каждого типа данныхВ основном второе издание книги, как и прежде, посвящено типам данных, к которым относятся множество (set), мультимножество (bag, или multiset), последовательный список (sequential list), упорядоченный список, для которого определен оператор "меньше" (ordered list), стек (stack), очередь (queue), таблица (table) и граф (graph). Рассматриваются также такие дополнительные типы данных, как очередь с приоритетами (priority qieue). Все эти типы данных описаны по единой схеме. Этап 1. Абстрактное описание типа данных. На этом этапе студент должен разбираться в типе данных и операциях над ним на уровне понятий и рисунков. Например, студент может изобразить стек и операции заталкивания и выталкивания элементов стека. Нужно понять и решить простые задачи, например, использование стека для изменения порядка следования букв в слове на противоположный. Этап 2. Создание спецификации типа данных в виде класса на языке С++. На этом этапе студент учится писать на языке С++ спецификацию класса, реализующего некоторый тип данных. Спецификация включает прототипы конструкторов, открытых функций-членов и других открытых членов класса (например, констант, определяющих максимальный размер стека). Прототип каждой функции-члена приводится вместе с контрактом о ее пред- и постусловиях, полностью описывающих поведение функции. На этом этапе студенту очень важно понимать, что спецификация совершенно не связана с конкретным способом реализации класса. Одну и ту же спецификацию можно использовать несколько раз для разных реализаций одного и того же типа данных. Этап 3. Использование типа данных. С помощью спецификации студенты могут создавать небольшие приложения или демонстрационные программы, иллюстрирующие использование типа данных. Эти приложения основаны исключительно на спецификации типа данных, поскольку по-прежнему не связаны ни с одной конкретной реализацией класса. Этап 4. Выбор подходящей структуры данных, проектирование и реализация типа данных. Имея хорошее абстрактное представление о типе данных, можно выбрать подходящую структуру данных, например, массив фиксированного размера, динамический массив, связанный список, состоящий из узлов, или бинарное дерево. Для многих типов данных на первых порах для проектирования и реализации применяется простой подход, например, использование массива фиксированного размера. Позднее тот же самый тип данных проектируется и реализуется заново на основе более сложной структуры данных. Поскольку в книге используются классы на языке С++, при реализации типов данных выбранные структуры становятся закрытыми переменными-членами соответствующего класса. Для каждого реализованного класса подчеркивается необходимость четкого понимания правил, которые связывают закрытые переменные-члены с абстрактным типом данных. Эти правила студенты должны формулировать на естественном языке в виде инварианта абстрактного типа данных. Затем они могут реализовывать разные функции-члены. Инвариант помогает правильно создавать функции, поскольку 1) предполагается, что инвариант каждой функции (за исключением конструкторов) выполняется в начале ее работы; 2) каждая функция (за исключением деструктора) должна гарантировать, что инвариант выполняется после завершения ее работы. Этап 5. Анализ реализации. Каждую реализацию можно проанализировать с точки зрения ее правильности, гибкости (например, фиксированный размер по сравнению с динамическим), а также времени выполнения (с помощью обозначения "О-большое"). Студентам полезно проанализировать вариант, при котором один и тот же тип данных реализуется разными способами. Что должны знать студенты по завершении курсаВ конце нашего курса студенты должны знать устройство типов данных, уметь использовать типы данных, реализовывать их разными способами, а также оценивать практический эффект реализаций типов данных. Студенты должны правильно оценивать эффективность реализации в терминах "О-большое" и обосновывать ее правильность, ссылаясь на инвариант класса. Типы данных в этой книге представляют собой упрощенные версии типов из стандартной библиотеки шаблонов Важным результатом изучения курса должен стать опыт спецификации, проектирования и реализации классов. Кроме того, повысится уровень рассуждений о программах вообще. Однако, возможно, наиболее важным станет умение выявлять классы, используемые в разных ситуациях. Теперь студенты не обязаны писать программы "с нуля". Прослушав этот курс, они смогут не только рассматривать задачу с точки зрения типов данных, необходимых для ее решения, но и определять, для какой ее части подойдет мультимножество, стек, очередь или что-нибудь еще. При этом выбранная часть будет именно тем, что нужно, и программистам не придется заново создавать необходимые классы. Вместо этого, они смогут просто вставить в свою новую программу разработанный ими на протяжении этого курса тип данных, например, мультимножество, стек или очередь, не внося в него никаких изменений. Еще более вероятно, что программисты обратятся за помощью к стандартным типам данных, например, к стандартной библиотеке шаблонов языка С++. Фактически, типы данных в э Другие основные темыНа протяжении курса освещаются и другие аспекты "настоящего програм-мирования". Объектно-ориентированное программирование. Глубокое понимание классов языка С++ создает хорошую основу для изучения объектно-ориентированного программирования. С самого начала книги вводятся важные свойства классов: понятие о функциях-членах, различие между закрытыми и открытыми членами, предназначение конструкторов и краткое описание перегруженных операторов. Этой информации достаточно для дальнейшей работы с классами. Другие важные аспекты, связанные с классами, вводятся после того, как студенты научатся использовать динамическую память (глава 4). Здесь нужно объяснить три дополнительных понятия: конструктор копирования, перегруженный оператор присваивания и деструктор. Изучение этих вопросов объектно-ориентированного программирования на примере использования динамической памяти дает студентам конкретное представление о ней как о ресурсе, который можно взять, а затем вернуть. С концептуальной точки зрения наибольшим достоинством объектно-ориентированного программирования является возможность повторного использования программного обеспечения. Есть много вариантов ввода понятия наследования в начале курса (например, реализация класса set как производного от класса bag). Однако если слишком рано ввести наследование, студенты могут утонуть в море новых понятий и не разобраться в основных структурах данных. По этой причине в нашем курсе наследование представлено в самом конце (разделы 14.1 и 14.2). Однако его можно рассматривать сразу после описания конструкторов копирования. Учитывая это, некоторые преподаватели могут излагать материал, содержащийся в главе 14, после описания стеков и очередей. Студенты, уже овладевшие основами программирования, могут разрабатывать проект, связанный с наследованием (например, моделирование экосистемы из раздела 14.2 или игрового автомата из раздела 14.3), пока остальные студенты осваивают классы. Шаблоны. Шаблонные функции и классы представляют собой важную часть стандартной библиотеки классов, позволяя программисту легко изменять тип элементов, содержащихся в контейнерном классе. Шаблонные классы позволяют также использовать разные конкретизации класса в одной и той же программе. Поскольку вычисление выражения - это важное приложение, в котором используются две разновидности стеков, следует научиться применять шаблонные классы (глава 6) прежде, чем изучать стеки (глава 7). Итераторы. Итераторы - еще одна важная часть стандартной библиотеки шаблонов, облегчающая программисту перемещение по элементам, которые содержатся в контейнере (например, элементам множества или мультимножества). Такие итераторы могут быть внутренними (т.е. реализовываться как функции-члены контейнерного класса) или внешними (т.е. реализовываться в виде отдельного класса, являющегося дружественным контейнерному классу). В книге вводятся внутренние итераторы для одного из первых контейнерных классов (последовательного списка, описанного в разделе 3.2). Затем внутренний итератор добавляется в класс bag (глава 6). Далее обсуждаются более сложные внешние итераторы. В результате этого обсуждения студенты должны убедиться в преимуществах внешних итераторов. На протяжении текста итераторы дают хорошую возможность создавать программные проекты, например, реализовать внешний итератор для класса bag (глава 6) или использовать стек в реализации внутреннего итератора для бинарного дерева (глава 10). Рекурсия. Рекурсию иногда преподают на первом курсе. Однако большинство примеров, рассматриваемых на первом курсе, ограничивается рекурсивным вызовом функции. Это может создать у студентов ложное впечатление, что рекурсия - это не более, чем цикл. Поэтому мы постарались избегать применения ограниченной рекурсии на втором курсе. Например, перемещение по списку и другие операции со связанными списками можно реализовать с помощью ограниченной рекурсии, однако в результате у студентов возникнет неправильное представление о рекурсии (причем ограниченно рекурсивные операции со списком, состоящим из тысяч элементов, изучать совсем не обязательно, поскольку их применение приводит к переполнению стека). Итак, на протяжении второго курса основной упор делается на рекурсивное решение, которое представляет собой намного более общее понятие, чем ограниченная рекурсия. В главе, посвященной рекурсии, приводятся три примера. Два из них - генерирование случайных фракталов и путешествие по лабиринту - пользуются большой популярностью у студентов. В нашем курсе рекурсия (глава 9) изучается до деревьев (глава 10), поскольку существуют алгоритмы для работы с деревьями, в которых рекурсия играет особо важную роль. Однако преподаватели, которые хотят выделить рекурсию, могут перенести эту тему вперед, даже до главы 2. Если у студентов достаточно времени для реализации проектов, посвященных работе с деревьями (глава 11), можно проанализирвать рекурсивные алгоритмы для работы с ними, объяснив важность сохранения равновесия в дереве - как для улучшения реализации, так и во избежание потенциального переполнения стека выполнения программы. Поиск и сортировка. В главах 12 и 13 освещаются основные вопросы, связанные с алгоритмами сортировки и поиска. Рассматривается бинарный поиск в упорядоченном списке, с которым многие студенты уже знакомы. В главе, посвященной поиску, вводятся также таблицы хеширования. В главе о сортировке описывается простой квадратичный метод сортировки, однако большая часть главы посвящена быстрым алгоритмам: рекурсивной сортировке вставками (наихудшая оценка времени выполнения которой равна O(n log n)), рекурсивная быстрая сортировка Хаара (со средним временем O(n log n)) и сортировка кучи, представленной в виде дерева (наихудшая оценка времени выполнения которой равна O(n log n)). В этой главе впервые описываются функции сортировки из стандартной библиотеки языка С++. Проекты повышенной сложностиМатериал, изложенный в книге, дает широкие возможности для создания проектов повышенной сложности, которые можно предложить основательно подготовленным студентам. К проектам повышенной сложности относятся следующие.
Особенности языка С++Язык С++ обладает многими особенностями, которые выходят за рамки второго курса. Однако мы стремились полностью осветить те вопросы, которых касались в ходе преподавания. В первом издании этой книги были описаны две особенности языка С++, являвшиеся новыми в то время: новый тип данных bool (раздел 2.1) и статические константные члены (раздел 3.1). В стандарте 1998 года требования, предъявляемые к статическим константным членам, были изменены. Эти изменения были отражены в тексте (теперь константа должна быть объявлена как внутри, так и вне определения класса). Другое основное изменение, внесенное стандартом 1998 года, - использование пространств имен, которое также было включено во второе издание. Оба этих изменения не поддерживаются старыми компиляторами. В этих случаях мы даем соответствующие рекомендации (см. приложение 5 "Работа со старыми компиляторами"), а также предоставляем помощь по загрузке и установке компилятора Gnu g++ (см. приложение 11). Очередность изложения материалаЭта книга написана так, что преподаватели могут изменять порядок изложения материала, ориентируясь на уровень подготовки студентов или собственные вкусы. Зависимости между главами изображены на рисунке. Линии, соединяющие два прямоугольника, означают, что тему, указанную в верхнем прямоугольнике, следует освещать раньше. Мы рекомендуем следующую последовательность изложения. Обычный курс. Начинаем с глав 1-10, пропуская часть главы 2, если студенты уже знакомы с классами языка С++. Большинство глав можно изложить в течение недели, но можно уделить больше времени главе 5 (связанные списки), главе 6 (рекурсия) или главе 10 (деревья). Обычно весь материал излагается за 13 недель, включая время на экзамены и дополнительное изучение списков и деревьев. Оставшееся время можно посвятить выполнению задания, связанного с деревьями из главы 11, или бинарному поиску (раздел 12.1) и сортировке (глава 13). Курс объектно-ориентированного программирования. Если студенты когда-либо уже изучали алгоритмы поиска и сортировки, можно уделить особое внимание объектно-ориентированному программированию. Сначала детально изучаются первые четыре главы, а затем вводятся производные классы -членам. Сокращенный курс. В течение первой недели три первые главы изучаются студентами самостоятельно, а преподавание начинается с главы 4 (указатели). Это высвобождает две-три недели в конце семестра, которые можно посвятить более глубокому изучению алгоритмов поиска, сортировки и других сложных тем (выделенных на схеме, иллюстрирующей взаимные зависимости между главами). Кроме того, курс можно дополнительно сократить, если не рассматривать стеки и очереди на лекциях, предложив студентами изучить эти темы самостоятельно. Изучение рекурсии и сортировки в начале курса. От одной до трех недель можно посвятить рассмотрению рекурсии и ее реализации. В этом случае сначала изучаются главы 1 и 9, сопровождаемые дополнительными заданиями, связанными с рекурсией. Если рекурсия излагается в начале курса, то бинарный поиск (раздел 12.1) и большинство алгоритмов сортировки (глава 13) можно преподавать до введения классов языка С++. Поддержка через ИнтернетЧитатели смогут найти в Интернет следующие материалы.
Использование Web-броузера. Для получения информации, касающейся доступа к этим материалам, обращайтесь к Web-странице: http://www.cs.colorado.edu/~main/dsoc.html Дополнительную информацию можно получить в издательстве Addison Wesley, послав письмо по адресам aw.cse@awl.com или main@colorado.edu. БлагодарностиМы начали писать эту книгу, когда Уолтер гостил у Майкла на факультете компьютерных наук в университете штата Колорадо (г. Боулдер) (University of Colorado in Boulder). Работа была завершена после того, как Уолтер вернулся на факультет технических и компьютерных наук в университете штата Калифорния (г. Сан-Диего) (University of California, San Diego). Мы благодарны обоим университетам за предоставленные технические средства, за прекрасных студентов и возможность общаться с коллегами, близкими нам по духу. Наши студенты оказали особенно ценную помощь - около 200 человек работали с первоначальными вариантами книги, вносили предложения, объясняли, как они изучают материал. Мы благодарим преподавателей, использовавших наш материал в своих курсах по структурам данных, за ценные замечания: Кэти Бишоп (Cathy Bishop), Мартина Бутшера (Martin Butscher), Джину Черри (Gina Cherry), Кортни Камсток (Courtny Comstock), Джона Джиллета (John Gillett), Ральфа Холлингсворта (Ralph Hollingsworth), Патрика Линна (Patrick Lynn), Эви Немет (Evi Nemeth), Гарри Ната (Gary Nutt), Рика Осборна (Rick Osborne) и Карла Финкельмана (Karl Winklmann). Книга подробно рецензировалась Вольфгангом Байном (Wolfgang Bein), Биллом Хенкли (Bill Hankley), Майклом Миллиганом (Michael Milligan), Джефом Паркером (Jeff Parker), Эндрю Райтом (Andrew Wright), Джоном Роузом (John Rose) и Эваном Цвайфелем (Evan Zweifel). Мы очень благодарны рецензентам второго издания: Джорджу Бебису (университет штата Невада, г. Рено) (George Babis (University of Nevada, Reno)), Джеймсу Бохи (колледж Симпсона) (James Bohy (Simpson College)), Девиду Челбергу (университет штата Огайо) (David Chelberg (Ohio University)), Зорану Дуричу (университет Джорджа Мейсона) (Zoran Duric (George Mason University)), Хорсоу Кайка (государственный университет Юго-Западного Техаса) (Khorsow Kaikhah (Southwest Texas State University)) и Рику Вагнеру (университет Южной Калифорнии) (Rick Wagner (University of Southern California)). Они выполнили особенно тяжелую работу, поскольку компиляторы, на которые ориентированы приведенные в книге программы, появились недавно. Мы выражаем благодарность редакторам и сотрудникам издательства Addison Wesly. Элинор Актипис (Elinor Actipis) ежедневно вдохновляла нас и облегчала нам путь к выпуску книги. Мы благодарны Джойс Кочентино (Joyce Cosentino) за прекрасный выбор цвета и дизайн обложки. Элен Рибенакер (Helen Reebenaker) помогала нам на каждом этапе производства, Джина Хейген (Gina Hagen) разработала элементы внутреннего дизайна книги. Спасибо Адриенне Ребелло (Adrienne Rebello) за переплет редакторской версии книги и Майклу Хиршу (Michael Hirsh) за окончательную подготовку материала к публикации. Особую благодарность мы выражаем нашему редактору Картеру Шанкину (Carter Shankin), который работал над книгой с самого начала и постоянно поддерживал нас. В заключение мы благодарим нашего редактора Сюзан Хартман (Susan Hartman) за постоянную поддержку, поощрение и руководство - без нее эта книга не вышла бы в свет! Кроме людей, работавших над книгой, мы признательны тем, кто проявлял к нашей работе постоянный интерес. Глубочайшая благодарность Лидии Окойн (Lydia Aucoin), Дэвиду Бенсону (David Benson), Стиву Бруксу (Steve Brookes), Полу Чедвику (Paul Chadwick), Эми Кронин (Amy Cronin), Дэну Дорману (Dan Dorman), Анджею Эренфойту (Andrzej Ehrengeucht), Полу Айсенбри (Paul Eisenbrey), Лойду Фосдику (Lloyd Fosdick), Рику Ловелу (Rick Lowell), Джорджу Мейну (George Main), Джиму Мартину (Jim Martin), Джиму Мартину-младшему (Jim Martin Jr.), Остину Мелтону (Austin Melton), Майклу Миллигану (Michael Milligan), Майклу Миславу (Michael Mislove), Филипу Мальри (Philip Mulry), Эви Немет (Evi Nemeth), Кэти Престон (Cathy Preston), Гарри Престону (Harry Preston), Гжегожу Розенбергу (Grzegorz Rozenberg), Дэвиду Шмидту (David Schmidt), Карлу Финкельману (Karl Winklmann), Эвану Цвайфелю (Evan Zweifel), Анне (Hannah), Тимоти (Timothy) и Джанет (Janet).
Майкл Мейн main@colorado.edu Боулдер, Колорадо
Уолтер Савитч wsavitch@ucsd.edu Сан-Диего, Калифорния
|
http://subscribe.ru/
E-mail: ask@subscribe.ru |
Отписаться
Убрать рекламу |
В избранное | ||