Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Связный список не понятный момент


Автор: lamber 4.4.2011, 22:43
Понимаю что по поводу такой базовой структуры написанно не мало, общая идея мне понятно все ясно кроме одного момента, перечетал массу ответов. но въехать не могу, видать тупой. не буду приводить реализацияю списка её и все так видели, приведу пример функции добавления нового элемента. Собственно в ней то и мне не понятно

Код

void comp_in(dyn_list &l, char* n, char* v)
{
    comp* c = new comp();
    strcpy_s(c->name, 20, n);
    strcpy_s(c->value, 10, v);
    c->next = NULL;
    if (chk_empty(l))
        l.head = c;
    else
        l.tail->next = c; //не понятны эти две строки эта
    l.tail = c; //и эта




взято отсюда http://www.codenet.ru/progr/cpp/dlist.php

Я как размышляю вот мы добавили первый элемент в список, собственно он на первом этапе и голова и хвост списка с этим все ясно. Добавляем второй элемент, заполняем строки данных зануляем указатель на следующий элемент. В блоке if что у нас получается следующий элемент хвоста присваивается созданный элемент, а в конце мы самому хвосту присваиваем этот же элемент, хрень какая-то выходит. Объясните плз этот момент для дураков плз )))

Автор: volatile 4.4.2011, 23:38
lamber, на codenet.ru я не заходил, вроде и так понятно.

Сначала немножко перепишу 

Код

if (chk_empty(l))
{    // Если список пуст голова и хвост списка устанавливаются на наш элемент 
     l.head = c; // голова
     l.tail = c; // хвост
}
else
{   // Если список не пуст
    l.tail->next = c; // берем последний элемент текущего списка и его поле next устанавливаем на наш элемент 
                      // так как наш элемент будет идти после него.

    l.tail = c;       // ну и теперь хвостом списка является не тот предыдущий, а наш элемент.
}
Вот собственно и все.
А так как строка
l.tail = c;
находится в обоих ветвях ифа, ее можно вынести, что и было сделано.

Автор: lamber 4.4.2011, 23:47
окей

Код

 l.tail->next = c;

тут вставляем последний элемент, но 

Код

l.tail = c; 


то получает что в первой операции l.tail->next содержало наш объект а после второй, l.tail->next будет содержать NULL т.к. в нашем объекте, c->next ==NULL. Я вот в ту тему въехать не могу, в принципе на словах я могу объяснить что тут происходит, но когда смотрю на код у меня вот так я его вижу.

Автор: Ozerich 5.4.2011, 00:03
Цитата

l.tail->next будет содержать NULL


А так и надо. l.tail это же последний элемент в списке

Автор: volatile 5.4.2011, 00:10
Цитата(lamber @  4.4.2011,  23:47 Найти цитируемый пост)
то получает что в первой операции l.tail->next содержало наш объект а после второй, l.tail->next будет содержать NULL т.к. в нашем объекте, c->next ==NULL.

Да правильно.
l.tail->next всегда должен содержать NULL.
l.tail - указатель на хвост
l.tail->next - следующий за хвостом элемент. (за хвостом элементов нет.)

Добавлено через 2 минуты и 32 секунды
а в первой операции он указывал на прошлый последний элемень, который теперь стал предпоследним. smile 

Автор: volatile 5.4.2011, 00:26
Цитата(Ozerich @  5.4.2011,  00:03 Найти цитируемый пост)
А так и не надо. l.tail это же последний элемент в списке.

я думаю вы опечатались. частица "не" лишняя

Добавлено через 1 минуту и 13 секунд
а уже исправили, ок smile 

Автор: lamber 5.4.2011, 12:09
С утра словил инсайт и сразу решил не заглядывая никуда на память. сделать свою реализацию ссписка. Все бы ничего но в программе где-то таится ошибка, т.к. в обычном режиме ничего не выводит, только когда бряки устанавливаешь и не печатает последнюю часть данных. Взгляните плз что не так.

Код

class Node
{
public:
    char name[64];
    char soname[256];
    Node* next;
};

class List
{
public:
    List();
    void append(char* name,char* soname);
    void ShowElements();
    void FillNode();
    ~List();
    Node* head;
    Node* tail;
};

List::List()
{
    this->head=NULL;
}
void List::append(char* name,char* soname)
{
    Node* item = new Node();
    strcpy(item->name,name);
    strcpy(item->soname,soname);
    item->next=NULL;
    if(this->head==NULL)
        this->head=item;
    else
        this->tail->next=item;
    this->tail=item;
}
void List::ShowElements()
{
    Node* node = new Node();
    node=this->head;
    while(node->next!=NULL)
    {
        printf("The name: %s and the soname: %s\n",node->name,node->soname);
        node=node->next;
    }


}
void List::FillNode()
{
    char name[64];
    char soname[256];
    while(true)
    {
        printf("Enter name and soname! \n");
        scanf("%s",name);
        if(!strcmp(name,"q"))
            break;
        scanf("%s",soname);

        this->append(name,soname);
    }

}
List::~List()
{
    printf("Deleting list...\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
    List list;
    list.FillNode();
    list.ShowElements();
    getchar();
    return 0;
}


Автор: Ozerich 5.4.2011, 12:45
В функции вывода элементов исправь условие выхода из цикла
Цитата

while(node!=NULL)

Автор: lamber 5.4.2011, 12:49
Агась уже сделал, осталось решить вопрос почему консользакрывается сразу а не ждет ввода символа.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)