Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.06.2008, 08:17   #11
Rembo
Форумчанин
 
Аватар для Rembo
 
Регистрация: 29.10.2007
Сообщений: 628
По умолчанию

MaTBeu, спасибо большое, вроде понял, но только в общих понятиях.
PS: извиняюсь, что-то 2-ва поста получилось, прочитайте пожалуйста следующее сообщение

Последний раз редактировалось Rembo; 07.06.2008 в 08:26.
Rembo вне форума Ответить с цитированием
Старый 07.06.2008, 08:23   #12
Rembo
Форумчанин
 
Аватар для Rembo
 
Регистрация: 29.10.2007
Сообщений: 628
По умолчанию

MaTBeu А вот как например использовать эту "гирлянду" на практике? Я могу, допустим, создать список из 2-ух элементов и члены второго объект заполнить данными?
2) Во многих самоучителях видел примеры, допустим функция, которая добавляет элемент, или функция, которая добавляет в конец элемент, или функция, которая удаляет элемент, ну вообщем такие примеры... Из них я только разобрался с функцией, которая добавляет элемент в начало списка, а остальные так же не понимаю. Вопрос: стоит ли в них досконально разбираться или же можно просто выучить эти функции?
Помогите пожалуйста. Если не сложно, ответьте на мои вопросы.

Последний раз редактировалось Rembo; 07.06.2008 в 08:29.
Rembo вне форума Ответить с цитированием
Старый 07.06.2008, 12:25   #13
Olympian
Форумчанин
 
Аватар для Olympian
 
Регистрация: 06.06.2008
Сообщений: 105
По умолчанию

Rembo Да, стоит разобраться. Потому что в С++ есть гораздо более сложные вещи. А списки - это база к обширному применинию - особенно деревья(Которые рекомендую учить сразу после списков).
Как таковые списки используются редко. Больше 2 вариант - Стек и Очередь. (Стек - первый пришел, последний ушел - пример стопка книг)
Очередь - первый пришел, первый ушел..Очередь в магазине

Вот они довольно широко используются.
Навскидку - разбор выражения, парсер и подобные программы используют стеки.
Извини - сейчас убегаю просто. Напиши какие функции тебе не понятны - объясню
Olympian вне форума Ответить с цитированием
Старый 07.06.2008, 14:30   #14
Rembo
Форумчанин
 
Аватар для Rembo
 
Регистрация: 29.10.2007
Сообщений: 628
Смущение

Olympian, спасибо. Прежде чем разбираться с функциями, я хочу понять общее назначение связанных списков. Ну вот например: массив нужен для создания многих переменных одного типа, например:
Код:
int massiv[20];
Тоесть создается переменные int massiv[0], int massiv[1] и т.д., и можно обратиться к любой переменной, а как вот обстоят дела со связанным списком? Допустим, вот в этой программе я добавил элемент в список: (сразу хочу спросить: если я первый раз добавляю элемент в список, то получается, что список состоит из одного объекта?):
Код:
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class NameDataSet
{
 public:
          int arg;
          NameDataSet* pNext;      
};
NameDataSet* pHead;
void addHead (NameDataSet* pLC)
{
pLC->pNext = pHead;
pHead = pLC;
return;
}
 
int main(int argc, char* pArgs[])
{
NameDataSet ob;
addHead(&ob);

system("PAUSE");
return 0;
}
Получается, что в этом списке находится один элемент, да?
А теперь главный вопрос: ну создал я допустим 3 таких объекта, связанных в списке, как мне теперь это использовать? могу ли я допустим заполнить члены 3-его объект какими-то данными? вот например в массиве можно:
Код:
massiv[2] = 15;
а тут что? или я вообще зря сравниваю массив со связанным списком? Помогите пожалуйста, когда будет время

Последний раз редактировалось Rembo; 07.06.2008 в 14:36.
Rembo вне форума Ответить с цитированием
Старый 07.06.2008, 15:18   #15
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

Цитата:
Сообщение от Rembo Посмотреть сообщение
Прежде чем разбираться с функциями, я хочу понять общее назначение связанных списков.
Ну например, когда вам из вередины массива необходимо добавить в середину элемент, то вам приходится использовать еще один вспомогательный массив. Это занимает определенное время. Для того, чтоб добавить элемент в список, вам всего лишь надо создать элемент и перенаправить на него указатель идущего перед ним элемента. У созданного элемента указатель надо направить на следующий за ним элемент.

Цитата:
Сообщение от Rembo Посмотреть сообщение
сразу хочу спросить: если я первый раз добавляю элемент в список, то получается, что список состоит из одного объекта?
да

Цитата:
Сообщение от Rembo Посмотреть сообщение
А теперь главный вопрос: ну создал я допустим 3 таких объекта, связанных в списке, как мне теперь это использовать? могу ли я допустим заполнить члены 3-его объект какими-то данными?
Ну как сказать... Можно. Только для этого вам нужно знать адрес третьего объекта. Когда я писала "базу данных" успеваемости студентов (элементом списка у меня был студент с оценками), я писала функцию, которая искала адрес необходимого мне элемента по фамилии студента. Получив адрес, я могла изменить данные о студенте.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 07.06.2008, 15:29   #16
Rembo
Форумчанин
 
Аватар для Rembo
 
Регистрация: 29.10.2007
Сообщений: 628
По умолчанию

ACE Valery, а можно, например написать функцию, которая добавит в члены 3-его элемента какие-либо данные? Или так просто этот 3-ий элемент не найти?
ЗЫ: а вот Вам как эти списки? быстро поняли эту тему? до меня че-то эта тема не очень доходит... А у Вас случайно не завалялся какой-нибудь справочник по связанным спискам в C++?

Последний раз редактировалось Rembo; 07.06.2008 в 15:32.
Rembo вне форума Ответить с цитированием
Старый 07.06.2008, 16:32   #17
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

Цитата:
Сообщение от Rembo Посмотреть сообщение
ACE Valery, а можно, например написать функцию, которая добавит в члены 3-его элемента какие-либо данные? Или так просто этот 3-ий элемент не найти?
Насколько я знаю, к элементу нельзя НИКАК обратиться, кроме как по адресу. Потому что мы не можем предусмотреть, где конкретно будет находиться при создании элемент. Он может быть в любо месте памяти.
Так что только через функцию поиска.

Цитата:
Сообщение от Rembo Посмотреть сообщение
ЗЫ: а вот Вам как эти списки? быстро поняли эту тему? до меня че-то эта тема не очень доходит...
Первые недели две для меня это было кошмаром. Потом ничего, привыкла. После того, как я написала функцию обмена местами первого и максимального элементов списка, функции добавления и удаления показались мне детским лепетом И не пытайтесь сравнивать список с массивом. Список - это список, у него просто другой принцип работы.

Цитата:
Сообщение от Rembo Посмотреть сообщение
А у Вас случайно не завалялся какой-нибудь справочник по связанным спискам в C++?
К сожалению, нет
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 07.06.2008, 16:47   #18
Rembo
Форумчанин
 
Аватар для Rembo
 
Регистрация: 29.10.2007
Сообщений: 628
По умолчанию

ACE Valery, а... ясно... Народ, а вот у кого-нибудь из Вас нету примера, демонстрирующего работу связанных списков? Ну например: есть класс:
Код:
class NameDataSet
{
 public:
   int nomer;     
   NameDataSet* pNext;      
};
Чтобы можно было бы вводить какой-нибудь номер. Допусти вел номер, а этот номер сохранился в члене int nomer, затем создался еще один элемент, можно еще вводить и так до бесконечности... А если например ввести end или exit, то на экран выводятся все данные членов, содержащихся в этих списках? Если у кого завалялся пример, киньте пожалуйста, чтобы посмотреть как работают эти списки в работе...
Rembo вне форума Ответить с цитированием
Старый 07.06.2008, 17:11   #19
filosof_x86
...
Форумчанин
 
Аватар для filosof_x86
 
Регистрация: 01.06.2008
Сообщений: 134
По умолчанию

Вот совсем недавно решал одну задачу, в которой требовалось использование двусвязанного списка. По условию задачи требовалось в текстовом файле найти все числа (среди слов и прочей хни), занести их в список и отсортировать список. В моем решение используется концепция сортировки списка по мере заполнения.

Код:
#include <stdio.h>
#include <stdlib.h>

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//                  блок работы с сортированным списком                       //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
struct item_sorted_list {
  item_sorted_list *next, *prev;
  int value;
};

struct sorted_list { item_sorted_list *begin, *end; };

sorted_list* alloc_sorted_list()
{
  sorted_list *l = (sorted_list *) malloc(sizeof(sorted_list));
  l->begin = l->end = 0;
  return l;
};

void free_sorted_list(sorted_list *l)
{
  if(l->begin) {
    while(l->begin->next) {
      l->begin = l->begin->next;
      free(l->begin->prev);
    }
    free(l->begin);
  }
  free(l);
}

void print_sorted_list(sorted_list *l, FILE *f) 
{
  item_sorted_list *p = l->begin;
  while(p) {
    fprintf(f, "%d\n", p->value);
    p = p->next;
  }
}

void insert(sorted_list *l, int value)
{
  item_sorted_list *item = (item_sorted_list *) malloc(sizeof(item_sorted_list));
  item->value = value;
  
  if(l->begin == 0) {                // список сейчас вообще пуст
    item->next = item->prev = 0;
    l->begin = l->end = item;
    return;
  }

  if(l->begin->value > value) {      // ставим в самое начало списка
    
    item->prev = 0;
    item->next = l->begin;
    l->begin = l->begin->prev = item;

  } else if(l->end->value < value) { // ставим в самый конец списка
    
    item->next = 0;
    item->prev = l->end;
    l->end = l->end->next = item;

  } else {                           // нужно найти место в середине списка

    item_sorted_list * p = l->begin->next;
    while((p != l->end) && (p->value < value)) p = p->next;
    item->next = p;
    item->prev = p->prev;
    p->prev = p->prev->next = item;
  }
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//               конец блока работы с сортированным списком                   //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

bool find_next_dig(FILE *f, char *buf)
{
  char *p;
  while(!feof(f)) {
    fscanf(f, "%255s", buf);
    for(p = (*buf=='-' && *(buf+1) ? buf+1 : buf); *p; p++) if(*p<'0' || *p>'9') break;
    if(*p) continue;
    return true;
  }
  return false;
}

int main()
{
  char buf[256];
  FILE *f = fopen("in.txt", "r");
  if(!f) {
    printf("error: in.txt\n");
    return 1;
  }
  sorted_list *list = alloc_sorted_list();
  while(find_next_dig(f, buf)) {
    insert(list, atoi(buf));
  }
  fclose(f);
  print_sorted_list(list, stdout);
  f = fopen("out.txt", "w");
  if(!f) {
    printf("error: out.txt\n");
    return 1;
  }
  print_sorted_list(list, f);
  fclose(f);
  free_sorted_list(list);
  return 0;
}
in.txt
Код:
123
321 hello
444 555f
-5 ff
out.txt
Код:
-5
123
321
444
P.S. это не C++, а C.
filosof_x86 вне форума Ответить с цитированием
Старый 07.06.2008, 18:12   #20
Rembo
Форумчанин
 
Аватар для Rembo
 
Регистрация: 29.10.2007
Сообщений: 628
По умолчанию

filosof_x86, спасибо, жаль только что не С++, просто в С вообще не пойму. Народ, вот все таки нашел пример работы со списками:
Код:
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;

class NameDataSet
    {
public:
char szFirstName[128];      
char szLastName [128];      
int nSocialSecurity;        
NameDataSet* pNext;
     };

NameDataSet* pHead = 0;

void addTail(NameDataSet* pNDS)
{
pNDS->pNext = 0;
if (pHead == 0)
{
pHead = pNDS;
return;
}

NameDataSet* pCurrent = pHead;
while(pCurrent->pNext)
{
pCurrent = pCurrent->pNext;
}
pCurrent->pNext = pNDS;
}
NameDataSet* getData()
{
NameDataSet* pNDS = new NameDataSet;
cout << "Введите имя ";
cin >> pNDS->szFirstName;

if ((stricmp(pNDS->szFirstName, "exit") == 0))
{
delete pNDS;
return 0;
}
cout << "Введите фамилию ";
cin >> pNDS->szLastName;
cout << "Введите номер социального страхования ";
cin >> pNDS->nSocialSecurity;
pNDS->pNext - 0;
return pNDS;
}
void displayData(NameDataSet* pNDS)
{
cout << pNDS->szFirstName
<< " "
<< pNDS->szLastName
<< "/"
<< pNDS->nSocialSecurity
<< "\n";
}

int main(int argc, char* pArgs[])
{
cout << "Считываем имя \ Фамилию социального страхования" << endl
<< "Введите 'exit' в поле имени для выхода" <<endl;
NameDataSet* pNDS;
while (pNDS = getData())
{
addTail(pNDS);
}
cout << "Элементы: " <<endl;
pNDS = pHead;
while(pNDS)
{
displayData(pNDS);
pNDS = pNDS->pNext;
}
system("PAUSE");
return 0;
}
Если не сложно, напишите пожалуйста подробные комментарии, желательно к каждой сточке (за исключением кончено таких как:#include <stdio.h>, операторов cin и cout, функцией main и system("PAUSE");
return 0; ) Кто может, помогите пожалуйста. Мне кажется, разобрав этот пример, я вникну в суть.

Последний раз редактировалось Rembo; 07.06.2008 в 22:16.
Rembo вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Связанные таблицы в Аксессе mirawoo Microsoft Office Access 8 12.03.2008 00:13
Не отображаются данные связанные с гл. таблицей? zimmion БД в Delphi 11 27.02.2008 18:50
Связанные таблицы - проблема при обращении к полю БД nataly_ukr БД в Delphi 7 13.11.2007 10:47
Добавление записей в связанные таблицы с помощью Навигатора ~MaGic~ БД в Delphi 2 09.07.2007 08:01