Краткие теоретические сведения

двухсвязаный список

 

            Ниже приведен текст учебной программы работы со связанным списком. Принимая имя файла в качестве параметра командной строки, программа читает содержимое указанного файла и на основе записей формирует двухсвязанный список. Звено списка задается структурой sp. Список распечатывается в прямом и обратном "направлении" и "уничтожается".

 

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

struct sp
{ sp * a_up; // указатель на выше стоящее звено
  sp * a_down; // указатель на ниже стоящее звено
  char info[81]; // информационная часть звена
};

int main(int argv, char * * argc)
{
  int k_zap=0, k;
  char z;
  char nfile[80], buf[80];
  FILE *h;
  sp *first, *a_tek, *p, *a_next;
  if (argv > 1 ) strcpy(nfile,argc[1]);
  else { printf("При вызове программы не указано имя файла для чтения.....\n"); return -2;};


// инициализация списка.....
  first=NULL;
//======
  h=fopen(nfile, "r");
  if (h == NULL )
   { printf( "Cannot open input file <%s> \n", nfile); return -1; };
//======

next:
   if ( fgets(buf, 80, h) == NULL )
    { printf( "Конец файла <%s> \n", nfile);
      goto endd;
    };
  k=strlen(buf)-1; if (k>=0) buf[k]='\0';
  k_zap++;
  printf("прочитали %d <%s>\n", k_zap, buf);

// поместить новую запись из buf в список
  if (first == NULL )
   {
     p = new sp; // адрес нового звена
     p->a_up=NULL; // в новом звене указатели вверх и вниз - пустые
     p->a_down=NULL;
     p->info[0]='\0'; // в новом звене инф. строка пустая
     strcpy(p->info, buf); // запись из буфера в инф. строку списка
     first=p; //голова списка

     printf("first=<%p>\n",first);
     printf("<%p><%p><%s>\n",p->a_up,p->a_down,p->info);
 
    }
  else
     {
// поиск последнего звена (показано для примера, на практике в этом нет необходимости)
       printf("***поиск последнего звена**\n");

       a_tek= first; // адрес текущего (первого) звена
       p = a_tek->a_down; // адрес "вниз" из текущего звена в указателе p
       printf("***текущее звено <%p><%p><%s>\n",a_tek->a_up, a_tek->a_down, a_tek->info);
       printf("***ук. на след. <%p>\n",p);
       while ( p != NULL )
         { a_tek=p; // адрес следующего звена
           p=a_tek->a_down; // адрес "вниз" из текущего звена в указателе p
          };
// в a_tek - адрес последнего звена

       p = new sp; // адрес нового звена

       printf("tek=<%p> new=<%p>\n", a_tek, p);
       a_tek->a_down = p; //ссылка вниз в предпоследнем звене
       p->a_up= a_tek; //ссылка вверх в последнем (новом) звене
       p->a_down=NULL;
       strcpy(p->info, buf);
       printf("<%p><%p><%s>\n",p->a_up,p->a_down,p->info);

     };

goto next;


endd:
fclose(h);
getchar();
// распечатка списка в прямом направлении ......
clrscr();
a_tek= first;
printf("first=<%p>\n",first);
p = a_tek; // ->a_down;
while ( p != NULL )
{
printf("ADD=<%p> ZVENO=<%p><%p><%s>\n",p, p->a_up,p->a_down,p->info);
getchar();
a_tek= p;
p = a_tek->a_down;
};
getchar();


// поиск последнего звена (показано для примера, на практике в этом нет необходимости)
printf("***поиск последнего звена**\n");
a_tek= first; // адрес текущего (первого) звена
p = a_tek->a_down; // адрес "вниз" из текущего звена в указателе p
printf("***текущее звено <%p><%p><%s>\n",a_tek->a_up, a_tek->a_down, a_tek->info);
printf("***ук. на след. <%p>\n",p);
while ( p != NULL )
{ a_tek=p; // адрес следующего звена
p=a_tek->a_down; // адрес "вниз" из текущего звена в указателе p
};
// в a_tek - адрес последнего звена

// распечатка списка в обратном направлении

p=a_tek->a_up; // адрес "вверх"
printf("*** последнее зв.<%p><%p><%s>\n",a_tek->a_up, a_tek->a_down, a_tek->info);
printf("***ук. на след. вверх <%p>\n",p);

while ( p != NULL )
{
printf("ADD=<%p> ZVENO=<%p><%p><%s>\n",p, p->a_up,p->a_down,p->info);
getchar();
a_tek= p;
p = a_tek->a_up;
};
getchar();

// удалить список из памяти
// поиск последнего звена
a_tek= first;
p = a_tek->a_down;
while ( p != NULL )
{
a_tek= p;
p = a_tek->a_down;

};

// в a_tek - адрес последнего звена
do
{
// адрес предыдущего звена
a_next=a_tek->a_up;
delete a_tek;
a_tek=a_next;
}
while ( a_tek !=NULL);

printf("усёёёё\n");
return 0;
}