Russian Qt Forum
Ноябрь 23, 2024, 17:49 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Проблемы с двухсвязным списком[РЕШЕНО]  (Прочитано 8394 раз)
Larry
Гость
« : Январь 08, 2012, 15:48 »

Доброе утро, форумчане! Помогите решить проблему. Есть функция добавления элементов в двухсвязный список
Код:
void add_link(char *name, link *item, link *parent)
{
    link *menu = NULL;
    menu = new link;
    if(menu == NULL)
    {
        std::cout << "Error" << std::endl;
        return NULL;
    }
    strcpy_s(menu->name, name);
    link *ptr = item;
    int count = 0;
    if(parent == NULL)
    {
        if(ptr == NULL)
        {
            menu->next = NULL;
            menu->previous = NULL;
        }
        else
        {
            link *last = NULL;
            while(ptr != NULL)
            {
                last = ptr;
                
                ptr = ptr->next;
            }
            menu->next = NULL;
            menu->previous = last;
        }
    }
    ptr = menu;
}
Но при вызове функции она возвращает пустой указатель. А если переписать ф-цию так
Код:
link* add_link(char *name, link *item, link *parent)
{
    link *menu = NULL;
    menu = new link;
    if(menu == NULL)
    {
        std::cout << "Error" << std::endl;
        return NULL;
    }
    strcpy_s(menu->name, name);
    link *ptr = item;
    int count = 0;
    if(parent == NULL)
    {
        if(ptr == NULL)
        {
            menu->next = NULL;
            menu->previous = NULL;
            //ptr = menu;
        }
        else
        {
            link *last = NULL;
            while(ptr != NULL)
            {
                last = ptr;
                
                ptr = ptr->next;
            }
            menu->next = NULL;
            menu->previous = last;
        }
    }
    ptr = menu;
    return ptr;
}
то все работает, только конечно возвращает указетель на конец списка. Объясните где ошибка?
« Последнее редактирование: Январь 09, 2012, 02:01 от Larry » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Январь 08, 2012, 16:34 »

Если Вы сказали что список двухсвязный, то должны быть его "голова" и "хвост"

Код
C++ (Qt)
void Add2List(link * item, link * prevItem, link *& head, link *& tail)
{
item->previous = prevItem;
 
item->next = prevItem ? prevItem->next : head;
if (item->next) item->next->previous = item;
else tail = item;
 
if (!prevItem) head = item;
else prevItem->next = item;
}
 
Лучше упаковать в класс (head и tail явно members)
« Последнее редактирование: Январь 08, 2012, 16:46 от Igors » Записан
Larry
Гость
« Ответ #2 : Январь 08, 2012, 22:23 »

Извините, но не смог ответить раньше. Спасибо, но в класс оборачивать не буду, т.к. это под микроконтроллер меню. Это даже не двухсвязный, а четырех:)..А обязательно иметь и голову и хвост? Можно ведь иметь только голову и дальше по указателям прыгать...
Записан
andrew.k
Гость
« Ответ #3 : Январь 08, 2012, 22:42 »

Извините, но не смог ответить раньше. Спасибо, но в класс оборачивать не буду, т.к. это под микроконтроллер меню. Это даже не двухсвязный, а четырех:)..А обязательно иметь и голову и хвост? Можно ведь иметь только голову и дальше по указателям прыгать...
Тогда это не будет двусвзязный список)
Записан
BRE
Гость
« Ответ #4 : Январь 08, 2012, 22:47 »

Тогда это не будет двусвзязный список)
Почему?
Двусвязный означает что каждый элемент знает предыдущий и следующий элемент.
Записан
Larry
Гость
« Ответ #5 : Январь 08, 2012, 22:55 »

Тогда это не будет двусвзязный список)
Почему?
Двусвязный означает что каждый элемент знает предыдущий и следующий элемент.
Вот я тоже так думаю:). А все-таки почему в передаваемом указателе ничего не сохраняется? В чем ошибка?
Записан
mutineer
Гость
« Ответ #6 : Январь 09, 2012, 00:33 »

Пардон, может я что не вкурил, но
1) с какими парметрами вызов функции происходит?
2) как void функция может возвращать пустой указатель?
Записан
Larry
Гость
« Ответ #7 : Январь 09, 2012, 00:41 »

это я обшибся при написании сообщения...в данном случае я передаю указатель link *item, где и хранится список. Но после вызова ф-ции он пустой...
Записан
mutineer
Гость
« Ответ #8 : Январь 09, 2012, 00:47 »

Есть как минимум одна ошибка - отсутствует last->next = menu;
Как я понимаю список передается не пустой в item?
Записан
Larry
Гость
« Ответ #9 : Январь 09, 2012, 01:16 »

Есть как минимум одна ошибка - отсутствует last->next = menu;
Как я понимаю список передается не пустой в item?
перед тем, как прочитал ваше сообщение ее и нашел Смеющийся...оказалось три ошибки Смеющийся
Рабочая функция выглядит так:
Код:
void add_link(char *name, link **item, link *parent)
{
link *menu = NULL;

menu = new link;

if(menu == NULL)
{
std::cout << "Error" << std::endl;
return;
}

strcpy_s(menu->name, name);

link *ptr = *item;

if(parent == NULL)
{
if(ptr == NULL)
{
menu->next = NULL;
menu->previous = NULL;

*item = menu;
}
else
{
link *last = NULL;

while(ptr != NULL)
{
last = ptr;

ptr = ptr->next;
}

menu->next = NULL;
menu->previous = last;

last->next = menu;
}
}
}
Спасибо за ответы...Подскажите пожалуйста почему при передаче указателя на структуру link *item функция не работает, а при передаче указателя на указатель link **item все нормально...чего-то не могу сообразить?
Записан
andrew.k
Гость
« Ответ #10 : Январь 09, 2012, 01:18 »

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

Каждый элемент знает следующий и предыдущий, какой смысл делать исключение для крайних? Об этом речь?
Записан
andrew.k
Гость
« Ответ #11 : Январь 09, 2012, 01:22 »

Спасибо за ответы...Подскажите пожалуйста почему при передаче указателя на структуру link *item функция не работает, а при передаче указателя на указатель link **item все нормально...чего-то не могу сообразить?
Потому что в одном случае ты передаешь указатель по значению и присваиваешь его внутри функции и наружу значение не попадает. Во втором ты передаешь указатель на указатель, поэтому можешь менять значение указателя и получать результат.

Можешь передавать указатель по ссылке (link * &item). Мне, например, так больше нравится)
Хотя наверное это не распространенная конструкция и закаленные сишники будут возражать)
Записан
Larry
Гость
« Ответ #12 : Январь 09, 2012, 02:00 »

Спасибо большое за ответы, очень помогли...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Январь 09, 2012, 14:05 »

Рабочая функция выглядит так:
Код:
void add_link(char *name, link **item, link *parent)
{
link *menu = NULL;

menu = new link;

if(menu == NULL)
{
std::cout << "Error" << std::endl;
return;
}

strcpy_s(menu->name, name);

link *ptr = *item;

if(parent == NULL)
{
if(ptr == NULL)
{
menu->next = NULL;
menu->previous = NULL;

*item = menu;
}
else
{
link *last = NULL;

while(ptr != NULL)
{
last = ptr;

ptr = ptr->next;
}

menu->next = NULL;
menu->previous = last;

last->next = menu;
}
}
}
Если parent != NULL, то созданный menu просто уплывет, будет утерян. Не видно зачем вообще подавать параметр parent

У Вас есть previous, но Вы добавляете в хвост пробегаясь до него (как обычно делают для односвязного списка).  Тогда лучше смотрится так

Код
C++ (Qt)
// использование
menu = AppendMenu(menu, CreateItem("name"));
 
// добавление в хвост
link * AppendMenu( link * menu, link * item )
{
item->previous = item->next = 0;  // это лучше сделать в CreateItem
if (!menu) return item;
 
link * last = menu;
while (last->next)
 last = last->next;
 
last->next = item;
item->previous = last;
return menu;
}
 
« Последнее редактирование: Январь 09, 2012, 14:11 от Igors » Записан
KontAr
Гость
« Ответ #14 : Март 24, 2012, 12:30 »

случайно забрел, но если нужен 4-связный список для контроллера, то может вот это может помочь: http://easyelectronics.ru/organizaciya-drevovidnogo-menyu.html#more-316
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.177 секунд. Запросов: 23.