![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
bylfer |
|
||||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 30.11.2010 Репутация: нет Всего: нет |
Доброго времени суток всем .
Видел много тем по спискам и структурам , но ничего похожего на мой случай не нашел , с программированием туго , потому решил создать тему , дабы все объяснили "в живую" . Суть задачи такова : Создать список студентов ( Имя , Фамилия , ДР , Группа ) Возможные действия : 1. Добавление в конец списка , либо редактирование существующего . 2а номеру 2. Удаление по 2б имени 2в фамилии 3а номеру 3. Сортировка по 3б имени 3в фамилии 4. Распечатка . Необходимо реализовать интерфейс , нажали (1) перешли выбирать а б или в . Функции необходимо прописывать до main , не засовывая их в head . Я попытался что то накалякать , но я никак не могу понять , как с этим работать , преподователь объяснить мне не желает , ибо счситает что должен сам разобраться . А это непосильно просто . Прошу помочь , модераторы если посчитают нужным - перенесите тему в нужный раздел . Всем заранее спасибо .
Классами пользоваться нельзя !!! Простите что не сказал , но их не было , а пробыват ими сдавать очень тяжко будет , мне бы в этом разобраться . По сортировке : необходимо организовать функцию , которая бы возвращала 0 или 1 , при сравнении кода букав в именах . Далеее как то воспользоваться пузырьком .
Извеняюсь за ужасный код , но на большее не тяну . При удалении необходимо перекидывать указатель элементов с пред идущего на последующий , благо фу-ия возвращающая ячейку по заданому номеру написана . Это сообщение отредактировал(а) bylfer - 1.12.2010, 20:12 |
||||
|
|||||
Чoо |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
Вообще это дело желательно упаковать в класс, тогда работать со списокм будет намного удобней.
Далее. Для удаления элементов из списка необходимо создать метод поиска, а еще до него - сортировки. Перед удалением вызывать сортировку по нужному критерию (смотря что удаляется) а потом, используя бинарный поиск, находить нужный элемент и удалять его. Для редактирования - тоже поиск надо будет вызывать. Но удаление и поиск так реализовывать только в том случае, если в методе раедактирования или удаления передается параметр, по которому надо удалять. А если надо редактировать или удалять текущий элемент списка, то тут еще проще: поиск не нужен. Вобщем если не разберетесь, набросаю что-нибудь вечерком. -------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Чoо, сортировка и бинарный поиск это конечно хорошо. Но они требуют возможности случайного доступа к элементам, а односвязный список данной возможностью не обладает.
Поэтому сортировку следует делать через отдельную функцию, которая будет переносить элементы в нужном порядке из одного списка в другой. Ну а от двоичного поиска следует отказаться в пользу простого перебора. Здесь элементов будет не так много, чтобы бинарный поиск как-то существенно себя оправдал. Короче. Следует делать как в STL (рекомендую к ознакомлению): поиск - найти элемент списка по какому-то критерию (функция) удаление - удалить указанный элемент из списка (метод) добавление - добавить элемент в конец списка (метод) сортировка - отсортировать список по указанному критерию (функция) |
|||
|
||||
Чoо |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
bsa, случайный доступ при поиске организовать не проблема, построив массив указателей на элементы списка, а вот сортировка да, проблема.
согласен, здесь бинарный поиск что из пушки по воробьям. Щас кратенько набросаю класс и функции, останется только организовать взаимодействие с программой в функции Main. Да вот еще. Еще когда я впервые познакомился с простим односвязным списком, я набросал краткую схему, котороая позволила наглядно представить, как работать с таким списком. Выложу чуть позже, так как надо переконвертить из формата visio. -------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
|||
|
||||
Чoо |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
ну примерно так:
единственное, что смущает, так это то, что я не сообразил как можно в параметрах функции вернуть указатель (ну в смысле не через return), поэтому удаление сделано немного криво (лишний поиск ![]() и смущает редактирование. А именно: можно ли было так переопределять присвоение, как я это сделал? ![]() ![]() Добавлено через 35 секунд что-то опять кода много ![]() Добавлено через 2 минуты и 39 секунд вовремя предупредили, ога ![]() Добавлено через 3 минуты и 17 секунд ну все же все-равно интересно услышать ответы на свои вопросы ![]() -------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
|||
|
||||
Чoо |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
вопщем глянул я свою схему (составление упорядоченного списка) - есть ошибки в ней. Исправлять лень, потому не буду выкладывать..
Теперь расскажу как надо создавать список. Без классов, так без классов, хотя с ними удобней.. Значит так. Первым делом надо определить структуру студент. Вы это сделали. Память для имени и Фамилии я бы выделял динамически. Ну если как проще, то оставим как есть. Структура следующая:
не вижу необходимости писать каждое слово с большой буквы. Далее. Что бы получить список, необходимо иметь хотя бы один указатель на головной элемент списка. Ну это понятно. В нашем случае нужно два элемента: голова и хвост. Поскольку ссылки только объявили, присвоим им адрес NULL. Тоесть указатель ни на что не указывает. Это понадобится в функции добавления элементов.
Теперь реализуем функцию добавления элементов. Что она должна делать? Она должна выделять память для нового элемента, корректировать указатель next, а так же возвращать адрес нового элемента, который впоследствие будет присвоен указателю head. Таким вот образом добавляется элемент в голову списка. Что бы вводить данные, используем функцию scanf (с ней вы должны быть знакомы). Всё просто:
Вернемся к функции Main. После создания головного элемента он же будет и хвостовым. поэтому tail = head. Поскольку я помогаю только со списком, а не интерфейсом, то список я заполню в цикле. Всего будет 5 элемента:
(пишу дальше..) Это сообщение отредактировал(а) Чoо - 2.12.2010, 01:06 -------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
||||||||
|
|||||||||
Чoо |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
с добавлением элемента в конец списка тоже все просто. Для этого не понадобится специальной функции. Достаточно будет в функцию add_list передать NULL, а результат присвоить указателю tail->next (это все в маин):
Следующим этапом напишу функцию, которая покажет наш список. Она должна принимать только указатель на голову списка. С этим вообще все просто ![]()
главная функция выглядит следующим образом:
-------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
||||||
|
|||||||
Чoо |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
Теперь напишу функцию для редактирования списка. В нее будет передаваться указатель на голову списка. Она будет выводить пошагово каждую запись до тех пор, пока пользователь не введет quit для выхода или edit для редактирования. Для показа следующего лемента нужно ввести что-нибудь кроме edit и quit:
в принципе вместо r можно использовать не массив символов а один символ, тогда scanf надо будет заменить на r = getchar(); Однако getchar у меня почему-то всегда, даже без ввода, возвращает последний символ. Добавлено через 30 секунд функция для проверки:
-------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
||||
|
|||||
Чoо |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
Делаем удаление. "По номеру" я так понял по порядковому номеру элемента в списке.
Делаю 2 функции: первая в качестве параметра принимает указатель на указатель на голову списка (о чем свидетельствует **) и номер элемента; вторая: указатель на указатель на голову, строку и булеву переменную, истина которой соответствует имени, а ложь - фамилии. Функцию del можно перегрузить:
Добавлено через 8 минут и 38 секунд пояню как происходит удаление. Если мы удаляем первый элемент списка, то достаточно указатель на голову перевести на следующий элемент, освободив память, занимаемую первым элементом. Кажется тут все понятно (11 строка) ![]() Если же нам нужно удалить элемент где-нибудь в середине, то для этого необходимо хранить адрес предыдущего элемента (*pre). при удалении надо сделать так, что бы указатель next из удаляемого элемента заменил указатель next предыдущего (можно так сделать, так как pre->next указывает на элемент, который мы сейчас удалим). после того, как указатели скорректировна, можно освободить память, занимаемую указателем curr. Вроде отже понятно объяснил. в принципе, строки 8 - 12 и 37 - 41 идентичны, поэтому можно их содержимое вынести в отдельную функцию, которую так же можно назвать del. сортировку списка я оставляю за автором. Правда не вижу смысла пузырьковой сортировки, намного проще сделать, как писали выше:
** p.s. наконец-то разобрался, как поменять указатель, который был передан в функцию ![]() Добавлено через 11 минут и 16 секунд p.p.s. Полный код того, что мы написали + проверка ![]()
-------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
||||||
|
|||||||
bylfer |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 30.11.2010 Репутация: нет Всего: нет |
Спасибо огромное , все доступно , и более - менее понятно . Алгоритм добавления я написал через цикл , также попытаюсь все собрать на выходных , в среду пойду сдаваться , потому будет возможность все оценить комплексно , пока разбераюсь , за проделаную работу спасибо .
|
|||
|
||||
Чoо |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
bylfer, Хорошо, что понятно
![]() Сортировка, по сути, будет копированием списка с выделением новой области данных, поэтому старую не забудьте освободить (пройтись в цикле от головы до хвоста и удалить каждый элемент). Удачи ![]() -------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
||||
|
||||
Чoо |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
да, про данные я забыл совсем
![]() ну а по поводу критерия: все же нужен, если мы не делаем функцию поиска. Каким образом мы тогда будем получать упорядоченный список? (конечно, если 3й параметр - адрес, то тогда критерии и не нужны. правда тогда надо будет написать и функцию поиска этого адреса) -------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
|||
|
||||
bylfer |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 30.11.2010 Репутация: нет Всего: нет |
Если речь идет о поиске адреса нужной ячейки , то это реализовано .
|
|||
|
||||
Чoо |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 22.9.2009 Репутация: 4 Всего: 4 |
bylfer, ну тогда действительно нужно только три параметра: Адрес головы, Даные и адрес ячейки, перед которой вставлять.
Да, про даные не забыл я оказывается, а получал их в функции. В принципе лучше в функцию передавать уже готовые даные, либо адрес на структуру, где они хранятся. Как успехи, кстати? ![]() -------------------- ![]() OS: Debian Squeeze (kernel 3.8.2) IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |