Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Примеры применений структур данных  (Прочитано 28824 раз)
0 Пользователей и 1 Гость смотрят эту тему.
eugrita
Помогающий

ru
Offline Offline

« : 24-03-2010 12:38 » 

Тема вопроса: в помощь изучающим программирование
пояснить на конкретных примерах классов задач
применение к ним конкретных структур данных
как-то: cписков, очередей, деков, стеков,
деревьев , графов.
Если с деревьями и графами классы достаточно обширны
(графы - транспортны задачи, сетевые, марковские процессы и пр)
деревья (деревья синтаксического разбора, классификационные и пр)
то в отношении cписков, очередей, деков, стеков у меня несмотря на основательное
изучение в течение неск лет осталось неясность (видимо и у других тоже).
Ну хорошо, по-моему самой ходовой структурой из этих является стек.
Типовая задача: построение калькулятора разного уровня сложности
 (выражения со скобками, без скобок с/без функций) - основа алгоритм Дейкстры использующий стек.
То по поводу самого списка и его частных случаев - дек, очередь все спорно.
1)список или массив? (и то и другое свои преимущества и недостатки)
(обычно аргумент в динамический массив сложнее вставлять, зато легче доступ по индексу, в списки- наоборот.
Есть и 2 концепции реализации списка а)на базе указателя на член данных
б) как массив .
Людям изучающим программирование и информатику все таки неясно:
1) когда массив, когда список? Возможны оба варианта
2) в отношении очередей и деков - не вижу класса задач где удобно применять именно
эти а не другие структуры.

Ну очередь queue -только может при имитационном моделировании систем массового обслуживания (СМО)
 но и это достаточно специальный класс задая.
Нет чтоб как в математике: понятие, например интеграл и дифф.ур. применяется
практически в любой науке - физика, экономика, химия и пр.
Помогите с примерами пожалуйста.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 24-03-2010 13:53 » 

хотел написать... даже написал... плюнул...
На безграмотно и не аккуратно написанный пост, не хочется отвечать. Жаль
Ведь вопрос требует осуждения, а что имеем на самом деле? Брошенная в сторону фраза с набором "специальных" терминов - стек, дек, очередь, граф.
Упоминание Дейсктра - к чему?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 24-03-2010 14:09 » 

Ничего не понял. Выбор структур определяется вовсе не классом задач, а классом методов решения задач.

Чисто математически связь между классами задач и структурами данных довольно слабая, так как для одного метода можно использовать инвариантные по смыслу структуры (массив, связный список); а для одного класса задач разработать разные методы, ориентированные на использование неинвариантных структур.

И уж тем более не существует в математике классов задач типа "задачи, решаемые при помощи деревьев", классификация обычно строится по проблемам.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
eugrita
Помогающий

ru
Offline Offline

« Ответ #3 : 24-03-2010 14:55 » 

Еще раз. Понимаю конечно, что есть альтернативные подходы к реализации алгоритма -
как-то со список / динамический массив .
Понимаю, что все изучавшие программирование серьезно в свое время проходили через школу типа
"сделай ручками список или стек или еще что" на примере конкретной задачи, например связать какую-то структуру в список , может и классы такие писали. Я тоже это делал
Таких людей я уважаю, только задачи на компьютерных практикумах обычно фиговые.
Например  типовая задача "база данных" студентов - массив структур реализовать в виде списка.
Сам реализовал, да только не могу себя убедить, а на фига список, когда с обычным динамическим массивом изящнее. Ну можно скидку на отсутствие поддержки STL в Pascal, Object Pascal, C
Но понимаю и других "белоручек", которым начхать на внутренние изучение структур типа список,
зато они работают на С++ в любой реализации, а там поддержка STL
и тот же самый список над которым потел реализатор БД студентов с STL делается буквально в 1 оператор
struct Stud {
             };
vector <stud > p, wS; //вот вам и динамический массив с доступом по индексу, т.е проще чем список
p.push_back(wS);// вставка в конец для стека
 p.Insert(i);//вставка в середину для списка
p.Remove(i);//удаление
извините, может синтаксис неточен, не в этом суть

Возникает иллюзия: а на фига все эти структуры данных если все так просто
"Выбор структур данных определяется не задачей а методом решения".
Конечно, любую задачу можно решать  разными методами - это не математика, где зачастую 1 метод. Но все таки, можно ли попытаться в выборе структур данных исходить не от метода,
а от задачи, навязывающей метод.Не понял
т.е. я хочу если возможно получить
Пример конкретной  типовой задачи, понятной и школьникам  матем. школы, где алгоритм решения серьезно проще если основан на списке очереди  деке.
Т.е. задачи, где выбор технологии реализации - не прихоть программиста, а определяется спецификой задачи. (пусть даже это задача на нейросеть)
Кроме калькулятора я ничего не могу привести в пример.
Этот мой вопрос,  риторический и адресован скорее не программистам, а постановщикам задач с математической культурой и кругозором. Хотя конечно задачи решаемые программистами шире и не всегда в основе имеют математическую модель
« Последнее редактирование: 24-03-2010 15:35 от eugrita » Записан
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 24-03-2010 15:59 » 

Цитата: eugrita
Конечно, любую задачу можно решать  разными методами - это не математика, где зачастую 1 метод. Но все таки, можно ли попытаться в выборе структур данных исходить не от метода, а от задачи.

Помоему эти два предложения явно противоречат друг другу. Да и если честно всё это выглядит крайне несуразно.

Лично мне это представляется примерно такой ситуацией. Надо мне попасть в другой город. Мне неминуемо придется сначала определиться насчет вида транспорта (то что здесь упоминается как метод). Например на поезде или на машие, а может вообще пешком. А уже потом покупать либо билет на поезд, либо бензин для авто, либо просто взять сухарей и одеть обувь полегче. Само по себе, то обстоятельство, что мне нужно переместиться в пространстве, никоим образом не даёт однозначного ответа на то, что мне для этого нужно, до тех пор пока я не выбиру способ/метод.
Записан
eugrita
Помогающий

ru
Offline Offline

« Ответ #5 : 24-03-2010 16:27 » 

В качестве конкретного алгоритма инициируемого задачей еще раз упомяну известный алгоритм Дейкстры
Разбор арифметического выражения:
Алг1. Вычисление арифметического выражения в постфиксной (польской) записи - использует стек и только стек.
(попробуйте именно эту задачу решать другим путем - если и решите - то на порядок сложнее. Недаром в промышленных калькуляторах используется аппаратно-реализованный стек.
Точно так же как разновидность
Алг.2 Преобразование арифметического выражения из обычной в польскую запись тоже - использует стек и только стек.
Точно так же
Алг.3 Одновременное преобразование вводимого в потоке арифметического выражения с одновременным преобразованием в польскую запись и вычислением результата (объединение Алг1. и Алг.2) использует 2 стека.
Вот вам пример такой всем понятной даже непрограммистам задачи. Сама задача - навязывает алгоритм решения с выбором стека.
Еще примеры будут???
« Последнее редактирование: 24-03-2010 16:30 от eugrita » Записан
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 24-03-2010 18:04 » 

Алг.2 Преобразование арифметического выражения из обычной в польскую запись тоже - использует стек и только стек.

Это кто такое сказал? Где это написано?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 24-03-2010 18:07 » 

Я бы сказал, что в разборе выражения больше подходит дерево. А стек к польской записи применим с другой стороны: сея запись заточена под стековую машину.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 24-03-2010 18:12 » 

Асолютно согласен с предыдущим оратором. Если перейти от голимой теории и полнейшей абстракции на уровень реального кода, то для реализации дерева имхо самой простой структурой в данном случае является многосвязный спискок. Это если конечно всё выражение должно храниться в памяти (возможно для каких-то манипуляций). А если нужно только вывести выражение на экран, то вообще ничего этого не надо, можно обойтись несколькими обычными переменными.
« Последнее редактирование: 24-03-2010 18:19 от resource » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 24-03-2010 18:28 » 

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

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 24-03-2010 18:32 » 

Список - это вырожденное дерево, состоящее из 1 ветви

Ну если список многосвязный, то я так понимаю, что ветвей уже может быть сколько угодно
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 24-03-2010 18:58 » 

eugrita, то есть, цель - придумать задачи для школьников, чтобы там структуры данных были не с потолка взяты, а реально являлись наиболее эффективными при решении задачи в конкретной постановке?

Под конкретной постановкой я имею в виду дополнительные ограничения, которые диктуют использование тех или иных структур. Это могут быть ограничения по ресурсам или требование "наиболее очевидного" (т.е. наиболее естественной структуры для представления тех или иных данных).
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 24-03-2010 19:23 » 

Господа отвечающие!
Я попрошу топикстартера оформить свой вопрос корректно, без лишних слов, аккуратно и с описанием существующей для него (топикстартера) проблемы дабы отделить бота от человека.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
eugrita
Помогающий

ru
Offline Offline

« Ответ #13 : 25-03-2010 05:04 » 

Да. моя цель  - придумать задачи для школьников, чтобы там структуры данных были не с потолка взяты, а реально являлись наиболее эффективными при решении задачи в конкретной постановке. При этом  еще в качестве основного критерия выбора способа реализации алгоритма была  не личная прихоть программиста, а скажем оптимизация алгоритма по скорости или числу операций.
Тогда сразу ясно, что алгоритмы использующие много операций вставок/удаления в середину массива выгодней реализовать списком с указателями. А алгоритмы, в которых много выборок из разных мест (много обращений к массиву) по сравнению с операциями вставок/удаления в середину - те лучше динамическими массивами.
Да еще чтоб  при этом задачи являлись не надуманными упражнениями, как сплошь и рядом мы видим в практикумах, а по-возможности типовыми алгоритмами, используемыми в практике.
« Последнее редактирование: 25-03-2010 05:09 от eugrita » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 25-03-2010 05:38 » 

Тогда сразу ясно, что алгоритмы использующие много операций вставок/удаления в середину массива выгодней реализовать списком с указателями.
ну так прямо утверждать тоже нельзя, зависит от многого. Например, в std::vector (или в простом массиве с простыми элементами, которые можно побайтово копировать) вставка в середину даже проще, чем в список, но, конечно, выполнится заметно дольше, если объём данных велик. Зато сам массив займёт гораздо меньше памяти, чем список.
Всё это ИМХО выбирается на основе поставленной задачи и опыта - ничего универсального тут не придумаешь

Нужно рассказать школьникам о существующих типах массивов/контейнеров, затем расказать о их плюсах и минусах - чтобы было представление о последствиях выбора хранилища данных. Дальше всё зависит от учеников - либо они будут понимать, как это использовать и в какой ситуации, и к чему это приведёт, либо нет. А решение задач - это лишь "набивка" руки
« Последнее редактирование: 25-03-2010 05:41 от Алексей1153++ » Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #15 : 25-03-2010 06:17 » 

Алексей1153++, поддерживаю. Что касается фразы которая тебя смутила, то я продолжу.

eugrita, цитата приведённая Алексеем показывает, что вы сами не до конца понимаете, чем придётся заплатить при выборе списка для данной конкретной задачи.
Список - это отсутствие быстрого доступа к элементам (доступа по индексу), последствия: лучше не сортировать и не искать. Естественно может быть список вам и пригодится, лично мне он пригодился всего пару раз, и то я добавлял/удалял элементы в конце/начале списка.
Думаю следует вас отправить к первоисточникам, т.е. Скотт Мейерс "Эффективное использование STL"

теперь конкретная задача:
1. 2*10^6 элементов, по 200 байт каждый. итого: примерно 400 мегабайт данных
2. необходимо производить быстрый поиск по различным критериям
3. периодически появляются новые элементы
4. старые элементы не удаляются
5. запрещено использовать контейнеры чувствительные к фрагментации памяти
6. запрещено перестраивать индексы

Внимание, вопрос: какие контейнеры вы будете использовать при реализации задачи (правда мне кажется пункты 4-6 слишком упростили задачу, ну да хрен с ними) ?
Записан

Странно всё это....
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 25-03-2010 08:13 » 

Список - это отсутствие быстрого доступа к элементам (доступа по индексу), последствия: лучше не сортировать и не искать. Естественно может быть список вам и пригодится, лично мне он пригодился всего пару раз, и то я добавлял/удалял элементы в конце/начале списка.

А мне вот список (восновном двусвязный) пригождался очень много раз. Хорош он тогда, когда в какой-то функции получаешь указатель на сам элемент списка. Таким образом отпадает надобность в том, чтобы перебирать список. И главное конечно достоинство списка (двусвязного) в том, что можно легко добавлять элемент в любую позицию, равно как и удалять.
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 25-03-2010 08:33 » 

resource, добавление-удаление всё-таки на красно-чёрных деревьях в общем случае поприятнее будет: всё-таки, в список вставка в произвольное место занимает линейное время.

Поэтому списки хороши в основном там, где нужно добавлять данные в голову и хвост. И если нужно быстро и без переаллокации отфильтровать хранимые данные (выбросить значения, не удовлетворяющие некоторому предикату). То есть, в тех задачах, где динамические массивы страдают от переаллокаций и перемещений элементов, а деревья избыточны, поскольку доступ к данным всегда последовательный.
Записан
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 25-03-2010 08:48 » 

Вад
Цитата: resource
когда в какой-то функции получаешь указатель на сам элемент списка. Таким образом отпадает надобность в том, чтобы перебирать список

Если же задача плоская - вставить элемент в 25ю (например) позицию, то согласен насчет линейного времени. Но с другой стороны, это всё равно лучше, чем вставка элемента в произвольную позицию массива (если эта позиция уже заполнена).
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 25-03-2010 09:09 » 

resource, я больше отвечал на вторую часть твоего высказывания Улыбаюсь А если вставка в список производится более частным образом, в заданном месте - тогда согласен. Скажем, слияние упорядоченных списков будет занимать всего лишь линейное время.

Вот и пример задачки - сортировка слиянием (merge sort) Улыбаюсь Хороша в случаях, когда объёмы сравниваемых данных большие - то есть, копирование стоит дорого.
« Последнее редактирование: 25-03-2010 09:13 от Вад » Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #20 : 25-03-2010 13:15 » 

если нужно много и часто вставлять куда попало (т.е. еще надо найти куда вставить), то имхо лучше деревьев ничего нету
хотя конечно можно вокруг списка построить обёртку из индекса и тогда эти проблемы уйдут, но тогда почему не взять дерево
Записан

Странно всё это....
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 25-03-2010 17:05 » 

Похоще, я уже перестал понимать. Я то всю жизнь думал, что дерево (о котором мы говорим) это скорее математическая абстракция, в то время как список это вполне реальный и конкретный способ организации данных.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 25-03-2010 17:36 » 

resource, бинарное дерево (например, красно-чёрное) - тоже вполне реальный и конкретный способ организации данных.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 25-03-2010 18:10 » 

я вот могу спокойно сказать, к примеру, что "реализовал в программе дерево с помощью списка", а наоборот не могу сказать.

в общем от теорий уже дышать трудно становится. Покажите код что ли какой-нибудь (не обязательно свой).
« Последнее редактирование: 25-03-2010 18:12 от resource » Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 25-03-2010 20:13 » 

Бинарное дерево - обычная рекурсивная структура. Такая же, кстати, как и список, только более ветвистая Улыбаюсь
Очень грубо:
Код:
template <typename ElemType>
struct Tree{
    Tree<ElemType> * left;
    Tree<ElemType> * right;
    ElemType value;
};
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #25 : 26-03-2010 04:11 » 

Вад, забыл указатель на корень Улыбаюсь

resource, вообще все  ассоциативные контейнеры (почти все Улыбаюсь угадай какие не деревья), это красно-чёрные деревья
и как я рассказывал Алексею в одном из топиков, эти контейнеры на самом деле 1 шаблонный класс, поведение которого немного меняется с помощью traits для получения уже финальной реализации

мы кстати отклонились от темы
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #26 : 26-03-2010 04:19 » 

битсет и вектор не деревянные )
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #27 : 26-03-2010 04:21 » 

а из ассоциативных ? Улыбаюсь
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 26-03-2010 04:23 » 

да я парочку знаю то ) Там их по списку туча, я не всё ещё пробовал
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 26-03-2010 06:54 » 

Вад, забыл указатель на корень Улыбаюсь
Умышленно Ага Для "просто дерева" это не обязательно - ибо дополнительная сущность, оптимизирующая работу с деревом. В Лиспе, вон, и односвязные списки являются встроенным типом данных.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines