LINUX.ORG.RU

связанные списки


0

0

Просьба сразу не пинать, ибо студент.

Разбираюсь с простым связанным списком, рассматриваю самый простой пример:

struct listnode {
   int data;
   struct listnode *next;
};

struct listnode *n1, *n2, *n3;

n1 = list_addnode();
n2 = list_addnode();
n3 = list_addnode();
...
/* work with the list */
...

list_freenode(n1);
list_freenode(n2);
list_freenode(n3);

Предположим, мне необходимо хранить несколько тысяч узлов. Очевидно, что заводить тысячи указателей n1..n1000 глупо. Что рекомендуется делать в таких случаях, т.е. память отведенную под узлы нужно аккуратно освобождать.

Заранее благодарю!

★★

typedef struct listnode {
int data;
struct listnode *next;
} listnode;

listnode *start, *end, *current;

start=end=NULL;

do {
current = (listnode*) malloc (sizeof(nistnode));
if (!current)
{
perror(" ");
exit(EXIT_FAILURE);
}
printf("Enter data= ");
scanf("%d",&current->data);

if(current->data<0)
{
free (current);
break;
}

if(start == NULL && end == NULL)

start=current;
else
end->next=current;

end=current;
end->next=NULL;

} while(1);


while(start!=NULL)
{
current=start->next;
free(current);
start=current;
}

Что-то типа такого, думаю поймёте.

Boy_from_Jungle ★★★★
()

Даааааа, чему сейчас студентов учат?
Почитай Кнута, хотя бы. И K&R заодно уж.
Или вот так: http://en.wikipedia.org/wiki/Linked_list для начала.
Кратко:
n1 = list_addnode();
n1->next = list_addnode();
n1->next->next = list_addnode();
или с итератором:
n1 = list_addnode();
n2 = n1->next;
n2 = list_addnode();
n2 = n2->next;
n2 = list_addnode();
Учи теорию.

tzukko
()

Я не понял ваш пример, обычно задействуют указатель "struct listnode *next". И отдельно держат указатель на начало списка, ну и иногда на конец. Или у вас там несколько тысяч списков?

mky ★★★★★
()

по ходу cruz7 не понимает назначение указателя next и причину присутствия "linked" в названии.

ef37 ★★
()
Ответ на: комментарий от ef37

Пугает фраза: "рассматриваю самый простой пример"
Может это у них препод такие примеры генерирует?

mky ★★★★★
()
Ответ на: комментарий от mky

>Может это у них препод такие примеры генерирует?
угу, с какого-нибудь форума!

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от mky

>Может это у них препод такие примеры генерирует?

Похоже, теорию вообще ниразу не изучали.

tzukko
()

массивы тоже хранишь в переменных arr1, arr2, arr3, ..., arr1000?

dilmah ★★★★★
()

>Очевидно, что заводить тысячи указателей n1..n1000 глупо.

google "массив"

Elverion
()

> Предположим, мне необходимо хранить несколько тысяч узлов. Очевидно, что заводить тысячи указателей n1..n1000 глупо. Что рекомендуется делать в таких случаях

Завести массив из 1000 указателей.

Ваш Капитан Очевидность.

www_linux_org_ru ★★★★★
()

связный список он потому и связный что перемещение по нему идет через связующие указатели от одного элемента списка к другому, а то что вы предлагаете это массив указателей на структуры)

если вы хотите перейти на тысячный элемент списка, то примерно так

struct listnode {
   int data;
   struct listnode *next;
} *start, *pos, *end;

/* заполнение списка */

pos = start;

for (int i = 0; i < 1000; i++)
    pos = pos->next;


хотя я конечно могу ошибаться - тоже студен и тоже 1 курс закончил только.

Dikar ★★
()
Ответ на: комментарий от Dikar

> хотя я конечно могу ошибаться - тоже студен и тоже 1 курс закончил только.

Можно так, можно и через массивы.
Через массив можно быстро перейти к нужному месту по индексу, это наверное единственный плюс такой реализации.

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от Boy_from_Jungle

>Да!, это будет массив однонаправленых списков.

Если я правильно понял автораЮ, он хочет один однонаправленный список, а не массив однонаправленных списков. И не понимает (не понимал) именно как расположить элементы списка и как их адресовать.

staseg ★★★★★
()
Ответ на: комментарий от staseg

>Да, только тогда это будет не связный список, а массив.

Это будет связный список поверх массива.

tzukko
()
Ответ на: комментарий от Boy_from_Jungle

Я бы сказал что тогда это будет массив указателей, дублирующих указатели перехода из связного списка, а, спрашивается, на кой ляд нам надо выделять лишние 998*4 байта (для 1000 элементов, потому что *start и *end уже есть и дублировать их - еще больший идиотизм)?

Dikar ★★
()
Ответ на: комментарий от Dikar

>Я бы сказал что тогда это будет массив указателей, дублирующих указатели перехода из связного списка, а, спрашивается, на кой ляд нам надо выделять лишние 998*4 байта (для 1000 элементов, потому что *start и *end уже есть и дублировать их - еще больший идиотизм)?

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

PS. Сколько байт отдается во славу новаторской идее не считал.

staseg ★★★★★
()
Ответ на: комментарий от tzukko

Спасибо за ответы, вроде разобрался. Заодно подскажите, где в сети можно скачать последние редакции Кнута.

cruz7 ★★
() автор топика
Ответ на: комментарий от Dikar

>потому что *start и *end уже есть и дублировать их - еще больший идиотизм

ну если ты их собрался дублировать, или использовать с массивом, то ты точно любишь заняться идиотизмом....

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от Boy_from_Jungle

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

Dikar ★★
()

смотреть у классиков (подсмотренно в Plan9):

struct listnode {
   int data;
   struct listnode *next;
};

struct listnode *n, **np, *tmpn,

np = &p;

while (...) {
        *np = list_addnode();
        np = &(*np)->next;
}

do_somthing_with(n);

while (n) {
        tmpn = n->next;
        free_node(n);
        n = tmpn;
}

beastie ★★★★★
()
Ответ на: комментарий от beastie

а вообще-то для этого есть <sys/queue.h>. это -- что бы не плодить лишние велосипеды. хотя в люнихи он слегка череж ж..у портирован -- не хватает как минимум половины функционала по-сравнению в bsd-шным оригиналом. почему это так -- для меня загадка.

beastie ★★★★★
()
Ответ на: комментарий от beastie

> а вообще-то для этого есть <sys/queue.h>. это -- что бы не плодить > лишние велосипеды. хотя в люнихи он слегка череж ж..у портирован --

Про queue.h в курсе, весьма удобно.

> не хватает как минимум половины функционала по-сравнению в bsd-шным > оригиналом. почему это так -- для меня загадка

в линуксе есть свое include/linux/list.h

cruz7 ★★
() автор топика
Ответ на: комментарий от beastie

> ну, во-первых не копипаст, а во-вторых посмотри внимательней да поразкинь мозгами

там не на что смотреть.

Boy_from_Jungle ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.