Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Помогите с программой ! Не могу осилить ! Список с редактированием , интерфейсом . 
V
    Опции темы
bylfer
Дата 1.12.2010, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 30.11.2010

Репутация: нет
Всего: нет



Доброго времени суток всем .

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

Суть задачи такова : 
Создать список студентов ( Имя , Фамилия , ДР , Группа ) 

Возможные действия : 

1. Добавление в конец списка , либо редактирование существующего .
                             
                              2а номеру
2. Удаление по     2б имени
                              2в фамилии

                                3а номеру
3. Сортировка по    3б имени
                                3в фамилии


4. Распечатка . 

Необходимо реализовать интерфейс , нажали (1) перешли выбирать а б или в . 
Функции необходимо прописывать до main , не засовывая их в head . 
Я попытался что то накалякать , но я никак не могу понять , как с этим работать , преподователь объяснить мне не желает , ибо счситает что должен сам разобраться . 
А это непосильно просто .
Прошу помочь , модераторы если посчитают нужным - перенесите тему в нужный раздел .
Всем заранее спасибо .


Код

#include <iostream>
using namespace std; // Необходимо подключить conlib.h  для интерфейса .

struct Student // так мы задаем нашу структуру 
{
    char Name[80];
    char SurName [80];
    int Bday ;
    int Group ; 
    Student* pNext;
};

void Enter (Student* pCur) // Сдесь я попытался реализовать функцию ввода , думаю она понадобится для редактирования .
{
    cout << "Input Name " ;
    cin >> pCur->Name; 

    cout << "Input SurName ";
    cin >> pCur->SurName;
    
    cout << "Input Bday ";
    cin >> pCur->Bday;
    
    cout << "Input Group ";
    cin >> pCur->Group;
    
}


 Student* Search (Student* pBegin,int number ) // функция по поиску нужного студента по номеру .
{
    int n=0;
    Student* pCur = pBegin;
    cout << "Input Number" ;
    cin >> number ;
    while (1)
    {
        pCur = pCur->pNext;
        if (n == number )
            break ;
        n++;
    }
    return pCur; // Возвращает ячейку с заданным номером .
}
void SetChenges (Student* pCur,Student* pBegin) // вызывается для редактирования .
{
    Student* Search(Student* pCur,Student* pBegin,int number);
    Enter(pCur);

}
void AddtoList(Student* pCur) 
{
    
}
void main()
{
    Student* pCur;
    int i ;
    for (i =0 ; i<3 ; i++)
    {
        pCur = new Student;
        Enter (pCur);
        AddtoList(pCur);
    }

    

}










Классами пользоваться нельзя !!!


Простите что не сказал , но их не было , а пробыват ими сдавать очень тяжко будет , мне бы в этом разобраться .

По сортировке : необходимо организовать функцию , которая бы возвращала 0 или 1 , при сравнении кода букав в именах .
Далеее как то воспользоваться пузырьком .


Код

Sort_Func ( )
{
          if ((int) a[i] > (int) b[i])
          // то вернуть 0 , или 1 
}


Извеняюсь за ужасный код , но на большее не тяну .

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

Это сообщение отредактировал(а) bylfer - 1.12.2010, 20:12
PM MAIL   Вверх
Чoо
Дата 1.12.2010, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



Вообще это дело желательно упаковать в класс, тогда работать со списокм будет намного удобней.
Далее. Для удаления элементов из списка необходимо создать метод поиска, а еще до него - сортировки. Перед удалением вызывать сортировку по нужному критерию (смотря что удаляется) а потом, используя бинарный поиск, находить нужный элемент и удалять его. 
Для редактирования - тоже поиск надо будет вызывать. Но удаление и поиск так реализовывать только в том случае, если в методе раедактирования или удаления передается параметр, по которому надо удалять. А если надо редактировать или удалять текущий элемент списка, то тут еще проще: поиск не нужен.
Вобщем если не разберетесь, набросаю что-нибудь вечерком.


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
bsa
Дата 1.12.2010, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



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

Короче. Следует делать как в STL (рекомендую к ознакомлению):
поиск - найти элемент списка по какому-то критерию (функция)
удаление - удалить указанный элемент из списка (метод)
добавление - добавить элемент в конец списка (метод)
сортировка - отсортировать список по указанному критерию (функция)
PM   Вверх
Чoо
Дата 1.12.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



bsa, случайный доступ при поиске организовать не проблема, построив массив указателей на элементы списка, а вот сортировка да, проблема. 
Цитата

Здесь элементов будет не так много, чтобы бинарный поиск как-то существенно себя оправдал.

согласен, здесь бинарный поиск что из пушки по воробьям.
Щас кратенько набросаю класс и функции, останется только организовать взаимодействие с программой в функции Main. 
Да вот еще. Еще когда я впервые познакомился с простим односвязным списком, я набросал краткую схему, котороая позволила наглядно представить, как работать с таким списком. Выложу чуть позже, так как надо переконвертить из формата visio. 


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
Чoо
Дата 1.12.2010, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



ну примерно так:
Код

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct student{
    char *name,
         *surname;
    int birthday,
        group;
    student *next;

    /*конструктор, который заполняет поля элемента списка*/
    student(const char *nm, const char *snm, int bday, int gr)
    {
        name = new char[strlen(nm)+1];
        strcpy(name,nm);

        surname = new char[strlen(snm)+1];
        strcpy(surname,snm);

        birthday = bday;
        group = gr;

        next = 0;
    }

    /*деструктор. Важно при удалении элементов списка
      освобождать память, занимаемую полями имя и фамилия*/
    ~student()
    {
        delete []name;
        delete []surname;
    }
    /*переопределим оператор =, что бы можно было присваивать элементы друг-другу*/
    student *operator =(student o)
    {
        name = (char *)realloc(name,sizeof(char)*strlen(o.name)+1);
        strcpy(name,o.name);

        surname = (char*)realloc(surname,sizeof(char)*strlen(o.surname)+1);
        strcpy(surname,o.surname);

        birthday = o.birthday;

        //next - оставляем таким каким был, что бы не нарушить список

        return this;
    }

};

class student_list{
private:
    student *head, *tail; //голова и хвост соотв.
    void show_rec(student *curr); //принимает указатель на текущий элемент и выводит его и все последующие
    void show_rec_rev(student *curr); //аналогично, но в обратном порядке
public:
    /*конструктор*/
    student_list() {head = tail = 0;}
    /*деструктор*/
    ~student_list(); //в деструкторе надо освободить память, занимаемую элементами списка и строками в них

    /*методы*/
    void addfirst(const char *nm, const char *snm, int bday, int gr); //добавляет элемент в начало списка
    void addlast(const char *nm, const char *snm, int bday, int gr); //добавляет элемент в конец списка
    void del(student *curr, student *pre); // удаляет элемент curr из списка
    void edit(student *curr, student *newst); //редактирует элемент curr
    void show(); //выводит все элементы списка на экран
    void showreverse(); //выводит все элементы списка с хвоста

    student *get_head() {return head;} //возвращает указатель на начало списка

};
/*деструктор*/
student_list::~student_list()
{
    while(head)
    {
        student *p = head->next;
        delete head;
        head = p;
    }
}
void student_list::addfirst(const char *nm, const char *snm, int bday, int gr)
{
    if(!head)
        head = tail = new student(nm,snm,bday,gr);
    else
    {
        student *p = new student(nm,snm,bday,gr);
        p->next = head;
        head = p;
    }
}
void student_list::addlast(const char *nm, const char *snm, int bday, int gr)
{
    if(!tail)
        head = tail = new student(nm,snm,bday,gr);
    else
    {
        student *p = new student(nm,snm,bday,gr);
        tail->next = p;
    }
}
void student_list::del(student *curr, student *pre)
{
    if(pre)
        pre->next = curr->next;
    delete curr;
}
void student_list::edit(student *curr, student *newst)
{
    *curr = *newst; //меняем данные, а не указатели
}

/*секция выводит список в прямом порядке*/
void student_list::show()
{
    show_rec(head);
}
void student_list::show_rec(student *curr)
{
    if(!curr) return;
    printf("%s %s %d %dгр.\n",curr->name, curr->surname, curr->birthday, curr->group);
    show_rec(curr->next);
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

/*секция выводит список в обратном порядке*/
void student_list::showreverse()
{
    show_rec_rev(head);
}
void student_list::show_rec_rev(student *curr)
{
    if(!curr) return;
    show_rec_rev(curr->next);
    printf("%s %s %d %dгр.\n",curr->name, curr->surname, curr->birthday, curr->group);
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
/* **********************************конец определения класса******************************/

/*функция сравнивает две структуры студент*/
bool studentcmp(const student *s1, const student *s2)
{
    /*будем считать, что отсутствие данных в каком либо поле ("" или -1)
      признак того, что это поле незначащее.
      если все поля незначащие, то критерию поиска удовлетворяет любой элемент
     */

    if((strcmp(s1->name,s2->name)!=0) && ((strcmp(s1->name,"")!=0) && (strcmp(s2->name,"")!=0) ))
        return false;
    if((strcmp(s1->surname,s2->surname)!=0) && ((strcmp(s1->surname,"")!=0) && (strcmp(s2->surname,"")!=0) ))
        return false;
    if((s1->birthday!=s2->birthday) && ((s1->birthday != -1) && (s2->birthday != -1)))
        return false;
    if((s1->group!=s2->group) && ((s1->group != -1) && (s2->group != -1)))
        return false;
    return true;
}

/*функция принимает заполненную структуру student и сравнивает ее с узлами списка.
  Если находит, то возвращает указатель на найденный элемент

*/
student *find(const student *curr, student *head)
{
    if(head)
    {
        if(studentcmp(head,curr))
            return head;
        find(curr,head->next);
    }
    else
      return 0;
}



/*функция удаляет элемент из списка
В функции происходит поиск, так как не нашел способ вернуть указатель на найденый
и предыдущий элементы.
*/

int del(student *s, student_list *o)
{
    bool find = 0;
    student *pre = 0, *head = o->get_head(), *curr = head;
    while(curr)
    {
        if(studentcmp(curr,s))
        {
            o->del(curr,pre);
            find = 1;
        }
        pre = curr;
        curr = curr ->next;
    }
    return find;
}

int main()
{
    student_list sl;
    /*пример заполнения списка*/
    sl.addfirst("qwe","rty",1999,1);
    sl.addfirst("asd","fgh",1998,2);
    sl.addfirst("zxc","vbn",1997,3);
    sl.addlast("poi","uyt",1996,4);

    /*привер отображения списка*/
    sl.show();
    printf("\n");
    sl.showreverse();

    /*примеры поиска в списке*/
    student *find_rec;
    find_rec = new student("asd","",-1,-1);
    if(find(find_rec,sl.get_head()))
        printf("Студент asd найден\n");
    else
        printf("студент asd  не найден\n");
    delete find_rec;

    find_rec = new student("dsa","",-1,-1);
    if(find(find_rec,sl.get_head()))
        printf("Студент dsa найден\n");
    else
        printf("студент dsa  не найден\n");
    delete find_rec;

    /*пример удаления из списка*/
    find_rec = new student("","",1998,-1);
    if(del(find_rec,&sl))
        printf("Запись найдена и удалена\n");
    delete find_rec;
    sl.show();

    printf("\n");

    /*пример редактирования*/
    student *new_rec;
    new_rec = new student ("hgf","dfg",1985,231);
    find_rec = new student("","",1997,-1);
    sl.edit(find(find_rec,sl.get_head()),new_rec);
    delete new_rec; delete find_rec;
    sl.show();

    return 0;
}

единственное, что смущает, так это то, что я не сообразил как можно в параметрах функции вернуть указатель (ну в смысле не через return), поэтому удаление сделано немного криво (лишний поиск smile ).
и смущает редактирование. А именно: можно ли было так переопределять присвоение, как я это сделал? smile. Впринципе можно и переписать без переопределения smile

Добавлено через 35 секунд
что-то опять кода много smile

Добавлено через 2 минуты и 39 секунд
Цитата(bylfer @  1.12.2010,  13:51 Найти цитируемый пост)
Классами пользоваться нельзя !!!

вовремя предупредили, ога user posted image

Добавлено через 3 минуты и 17 секунд
ну все же все-равно интересно услышать ответы на свои вопросы smile


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
Чoо
Дата 2.12.2010, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



вопщем глянул я свою схему (составление упорядоченного списка) - есть ошибки в ней. Исправлять лень, потому не буду выкладывать.. 
Теперь расскажу как надо создавать список. Без классов, так без классов, хотя  с ними удобней.. 
Значит так. Первым делом надо определить структуру студент. Вы это сделали. Память для имени и Фамилии я бы выделял динамически. Ну если как проще, то оставим как есть.
Структура следующая:
Код

struct student // так мы задаем нашу структуру 
{
    char name[80],
         surname [80];
    int bday,
        group;
    student *next;
};

не вижу необходимости писать каждое слово с большой буквы. 

Далее. Что бы получить список, необходимо иметь хотя бы один указатель на головной элемент списка. Ну это понятно. В нашем случае нужно два элемента: голова и хвост. Поскольку ссылки только объявили, присвоим им адрес NULL. Тоесть указатель ни на что не указывает. Это понадобится в функции добавления элементов. 

Код

int main()
{
    student *head = NULL, *tail = NULL;

    return 0;
}


Теперь реализуем функцию добавления элементов. Что она должна делать? Она должна выделять память для нового элемента, корректировать указатель next, а так же возвращать адрес нового элемента, который впоследствие будет присвоен указателю head. Таким вот образом добавляется элемент в голову списка.  Что бы вводить данные, используем функцию scanf (с ней вы должны быть знакомы). Всё просто:
Код

student *add_list(student *head)
{
    student *p;
    p = new student;
    printf("Введите через пробел Имя, Фамилию, День рождения и группу студента...\n");
    scanf("%s %s %d %d",p->name, p->surname, &p->bday, &p->group);
    if(head)
    {
        p->next = head;
        head = p;
        return p;
    }

    p->next = 0;

    return p;
}

Вернемся к функции Main. После создания головного элемента он же будет и хвостовым. поэтому tail = head. Поскольку я помогаю только со списком, а не интерфейсом, то список я заполню в цикле. Всего будет 5 элемента:
Код

int main()
{
    student *head = NULL, *tail = NULL;
    head = add_list(head);
    tail = head;
    for(int i = 0; i<4; ++i)
        head = add_list(head);    

    return 0;
}

(пишу дальше..)

Это сообщение отредактировал(а) Чoо - 2.12.2010, 01:06


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
Чoо
Дата 2.12.2010, 01:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



с добавлением элемента в конец списка тоже все просто. Для этого не понадобится специальной функции. Достаточно будет в функцию add_list передать NULL, а результат присвоить указателю tail->next (это все в маин):
Код

tail->next = add_list(NULL);

Следующим этапом напишу функцию, которая покажет наш список. Она должна принимать только указатель на голову списка. С этим вообще все просто smile:
Код

void show(student *head)
{
    if(head)
    {
        printf("%s %s %d %d\n", head->name, head->surname, head->bday, head->group);
        show(head->next);
    }
}

главная функция выглядит следующим образом:
Код

int main()
{
    student *head = NULL, *tail = NULL;
    head = add_list(head);
    tail = head;
    for(int i = 0; i<2; ++i)
        head = add_list(head);
    /* добавляем в конец списка*/
    tail->next = add_list(NULL);
    show(head);

    return 0;
}
обратите внимание на порядок вывода элементов.



--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
Чoо
Дата 2.12.2010, 02:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



Теперь напишу функцию для редактирования списка. В нее будет передаваться указатель на голову списка. Она будет выводить пошагово каждую запись до тех пор, пока пользователь не введет quit для выхода или edit для редактирования. Для показа следующего лемента нужно ввести что-нибудь кроме edit и quit:
Код

void editlist(student *head)
{
    student *curr = head;
    while(curr)
    {
        printf("%s %s %d %d\n-", curr->name, curr->surname, curr->bday, curr->group);
        char r[5];
        scanf("%s",r);
        if(strcmp(r,"quit")==0)
        {
            printf("редактирование прервано...\n");
            return;
        }
        else
        if(strcmp(r,"edit")==0)
        {
            printf("введите новые даные\n   ");
            scanf("%s %s %d %d",curr->name, curr->surname, &curr->bday, &curr->group);
        }
        curr = curr->next;
    }
    printf("редактирование завершено...\n\n");
}

в принципе вместо r можно использовать не массив символов а один символ, тогда scanf надо будет заменить на r = getchar();
Однако getchar  у меня почему-то всегда, даже без ввода, возвращает последний символ.

Добавлено через 30 секунд
функция для проверки:
Код

int main()
{
    student *head = NULL, *tail = NULL;
    head = add_list(head);
    tail = head;
    for(int i = 0; i<2; ++i)
        head = add_list(head);
    /* добавляем в конец списка*/
    tail->next = add_list(NULL);
    show(head);

    /*редактирвание списка*/
    printf("редактирование списка\n");
    editlist(head);
    show(head);

    return 0;
}



--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
Чoо
Дата 2.12.2010, 03:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



Делаем удаление. "По номеру" я так понял по порядковому номеру элемента в списке.
Делаю 2 функции: первая в качестве параметра принимает указатель на указатель на голову списка (о чем свидетельствует **) и номер элемента; вторая: указатель на указатель на голову, строку и булеву переменную, истина которой соответствует имени, а ложь - фамилии.
Функцию del можно перегрузить:
Код

int del(student **head, int number)
{
    student *pre = 0, *curr = *head;
    for(int i = 1; curr; i++)
    {
        if(i==number)
        {
            if(pre)
                pre->next = curr->next;
            else
                *head = curr->next;
            delete curr;
            return 1;
        }
        pre = curr;
        curr = curr->next;
    }
    return 0;
}
int del(student **head, const char *s, bool name)
{
    student *pre = 0, *curr = *head;
    bool to_del;
    while(curr)
    {
        to_del = false;
        if(name)
        {
            if(strcmp(curr->name,s)==0)
                to_del = true;
        }
        else
            if(strcmp(curr->name,s)==0)
                to_del = true;
        if(to_del)
        {
            if(pre)
                pre->next = curr->next;
            else
                *head = curr->next;
            delete curr;
            return 1;

        }
        pre = curr;
        curr = curr->next;
    }
    return 0;
}


Добавлено через 8 минут и 38 секунд
пояню как происходит удаление. 
Если мы удаляем первый элемент списка, то достаточно указатель на голову перевести на следующий элемент, освободив память, занимаемую первым элементом. Кажется тут все понятно (11 строка) smile
Если же нам нужно удалить элемент где-нибудь в середине, то для этого необходимо хранить адрес предыдущего элемента (*pre). при удалении надо сделать так, что бы указатель next из удаляемого элемента заменил указатель next предыдущего (можно так сделать, так как pre->next указывает на элемент, который мы сейчас удалим). после того, как указатели скорректировна, можно освободить память, занимаемую указателем curr. 
Вроде отже понятно объяснил. 
в принципе, строки 8 - 12 и 37 - 41 идентичны, поэтому можно их содержимое вынести в отдельную функцию, которую так же можно назвать del.
сортировку списка я оставляю за автором. Правда не вижу смысла пузырьковой сортировки, намного проще сделать, как писали выше:
Цитата(bsa @  1.12.2010,  14:39 Найти цитируемый пост)
Поэтому сортировку следует делать через отдельную функцию, которая будет переносить элементы в нужном порядке из одного списка в другой. 


**
p.s. наконец-то разобрался, как поменять указатель, который был передан в функцию  smile

Добавлено через 11 минут и 16 секунд
p.p.s. Полный код того, что мы написали + проверка smile
Код

#include <stdio.h>
#include <string.h>


struct student // так мы задаем нашу структуру
{
    char name[80],
         surname [80];
    int bday,
        group;
    student *next;
};

student *add_list(student *head)
{
    student *p;
    p = new student;
    printf("Введите через пробел Имя, Фамилию, День рождения и группу студента...\n");
    scanf("%s %s %d %d",p->name, p->surname, &p->bday, &p->group);
    if(head)
    {
        p->next = head;
        head = p;
        return p;
    }

    p->next = 0;

    return p;
}
void show(student *head)
{
    if(head)
    {
        printf("%s %s %d %d\n", head->name, head->surname, head->bday, head->group);
        show(head->next);
    }
    return;
}


void editlist(student *head)
{
    student *curr = head;
    while(curr)
    {
        printf("%s %s %d %d\n-", curr->name, curr->surname, curr->bday, curr->group);
        char r;
        r = getchar();
        printf("СИМВОЛ: %c",r);
        if(r=='q')
        {
            printf("редактирование прервано...\n");
            return;
        }
        else
        if(r=='e')
        {
            printf("введите новые даные\n   ");
            scanf("%s %s %d %d",curr->name, curr->surname, &curr->bday, &curr->group);
        }
        curr = curr->next;
    }
    printf("редактирование завершено...\n\n");
}

int del(student **head, int number)
{
    student *pre = 0, *curr = *head;
    for(int i = 1; curr; i++)
    {
        if(i==number)
        {
            if(pre)
                pre->next = curr->next;
            else
                *head = curr->next;
            delete curr;
            return 1;
        }
        pre = curr;
        curr = curr->next;
    }
    return 0;
}
int del(student **head, const char *s, bool name)
{
    student *pre = 0, *curr = *head;
    bool to_del;
    while(curr)
    {
        to_del = false;
        if(name)
        {
            if(strcmp(curr->name,s)==0)
                to_del = true;
        }
        else
            if(strcmp(curr->name,s)==0)
                to_del = true;
        if(to_del)
        {
            if(pre)
                pre->next = curr->next;
            else
                *head = curr->next;
            delete curr;
            return 1;

        }
        pre = curr;
        curr = curr->next;
    }
    return 0;
}

int main()
{
    student *head = NULL, *tail = NULL;
    head = add_list(head);
    tail = head;
    for(int i = 0; i<2; ++i)
        head = add_list(head);
    /* добавляем в конец списка*/
    tail->next = add_list(NULL);
    show(head);

    /*редактирвание списка*/
    printf("редактирование списка\n");
    editlist(head);
    show(head);

    /*удаляем по номеру*/
    printf("введите номер для удаления... ");
    int i=0;
    scanf("%d",&i);
    if(del(&head,i))
        printf("Элемент под номером %d удален\n",i);
    else
        printf("Элемент под номером %d не найден\n",i);
    show(head);


    /*удаляем по имени*/
    printf("введите имя для удаления... ");
    char buf[80];
    scanf("%s",buf);
    if(del(&head,buf,1))
        printf("студент %s удален\n",buf);
    else
        printf("студент %s не найден\n",buf);
    show(head);

    /*удаляем по фамилии*/
    printf("введите фамилию для удаления... ");
    scanf("%s",buf);
    if(del(&head,buf,0))
        printf("студент %s удален\n",buf);
    else
        printf("студент %s не найден\n",buf);
    show(head);


    return 0;
}




--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
bylfer
Дата 3.12.2010, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 30.11.2010

Репутация: нет
Всего: нет



Спасибо огромное , все доступно , и более - менее понятно . Алгоритм добавления я написал через цикл , также попытаюсь все собрать на выходных , в среду пойду сдаваться , потому будет возможность все оценить комплексно , пока разбераюсь , за проделаную работу спасибо .
PM MAIL   Вверх
Чoо
Дата 3.12.2010, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



bylfer, Хорошо, что понятно smile. Когда будете делать сортировку, я так думаю, что  лучше всего будет изменить функцию AddList, что бы она принимала два параметра: 1. Как и есть, голову списка; 2. Критерий, по которому надо отсортировать (например 1 - по имени, 2 - по фамилии, 3 - по номеру (скорее всего под номером имелся номер группы, тогда вам придется переделать функцию удаления по номеру, это не трудно) и 4 - без сортировки; 4 - не обязательно). 
Сортировка, по сути, будет копированием списка с выделением новой области данных, поэтому старую не забудьте освободить (пройтись в цикле от головы до хвоста и удалить каждый элемент).

Цитата(bylfer @  3.12.2010,  22:07 Найти цитируемый пост)
в среду пойду сдаваться

Удачи smile



--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
bsa
Дата 6.12.2010, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(Чoо @  4.12.2010,  00:42 Найти цитируемый пост)
лучше всего будет изменить функцию AddList, что бы она принимала два параметра

Цитата(Чoо @  4.12.2010,  00:42 Найти цитируемый пост)
2. Критерий, по которому надо отсортировать
Зачем?!? AddList второй параметр может быть только данные. Я бы сделал еще 3-й параметр - адрес элемента, перед которым добавить новый элемент (по умолчанию NULL - конец списка).

PM   Вверх
Чoо
Дата 6.12.2010, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



да, про данные я забыл совсем smile
ну а по поводу критерия:
все же нужен, если мы не делаем функцию поиска. Каким образом мы тогда будем получать упорядоченный список? (конечно, если 3й параметр - адрес, то тогда критерии и не нужны. правда тогда надо будет написать и функцию поиска этого адреса)


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
bylfer
Дата 6.12.2010, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 30.11.2010

Репутация: нет
Всего: нет



Если речь идет о поиске адреса нужной ячейки , то это реализовано . 
PM MAIL   Вверх
Чoо
Дата 6.12.2010, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



bylfer, ну тогда действительно нужно только три параметра: Адрес головы, Даные и адрес ячейки, перед которой вставлять. 
Да, про даные не забыл я оказывается, а получал их в функции. В принципе лучше в функцию передавать уже готовые даные,  либо адрес на структуру, где они хранятся.
Как успехи, кстати? smile


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1062 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.