Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебное пособие ОАиП.doc
Скачиваний:
13
Добавлен:
25.04.2019
Размер:
2.63 Mб
Скачать

Односвязный линейный список, очередь

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

Очередь организована по принципу FIFO - ”первый вошел - первый вышел”. Для очереди определены следующие операции:

- проверка очереди на пустоту;

- добавление нового элемента в конец (хвост) очереди;

- удаление элемента из начала (головы) очереди;

- поиск и модификация элемента в очереди.

- упорядочивание элементов очереди.

Ниже приводится текст программы, иллюстрирующий работу с однонаправленной очередью.

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <string.h>

struct zap {char inf[50];

zap *nx;};

void add(zap **,zap **);

void del(zap **,zap **);

void del_any(zap **,zap **,char *);

void see(zap *);

void sort(zap **);

void main(void)

{ zap *h,*t; // указатели на годову и хвост очереди

char l,*st;

st=(char *)malloc(10);

h=t=NULL;

// clrscr();

while(1)

{ puts("\nвид операции: 1-создать очередь");

puts(" 2-вывод содержимого очереди");

puts(" 3-удаление элемента из очереди");

puts(" 4-удаление любого элемента из очереди");

puts(" 5-сортировка очереди");

puts(" 0-окончить");

fflush(stdin);

switch(getch())

{ case '1': add(&t,&h); break; // добавление в хвост очереди

case '2': see(h); break; // просмотр с головы очереди

case '3': if(h) del(&t,&h); break; // удаление с головы очереди

case '4': if(h) // удаление с любого места в очереди

{ fflush(stdin);

puts("Введите информацию для удаления ");

gets(st);

del_any(&t,&h,st);

} break;

case '5': if (h) sort(&h); break;

case '0': return;

default: printf("ошибка, повторите \n");

}

}

}

// функция создания очереди

void add(zap **t,zap **h)

{ zap *n;

puts("Создание очереди \n");

do

{ if(!(n=(zap *) calloc(1,sizeof(zap))))

{ puts("Ошибка выделения памяти");

return;

}

puts("Введите информацию ");

scanf("%s",n->inf);

if (!*t) // очередь еще не создана

*t=*h=n; // устанавливаем оба указателя (голова и хвост)

// на единственный элемент очереди

else // очередь уже существует

{ (*t)->nx=n; // добавляем очередной элемент очереди

*t=n; // передвигаем указатель на хвост

}

puts("Продолжить (y/n): ");

fflush(stdin);

} while(getch()=='y');

}

// функция вывода содержимого очереди

void see(zap *h)

{ puts("Вывод содержимого очереди\n");

if (!h)

{ puts("Очередь пуста");

return;

}

do

{ printf("\n %s",h->inf);

h=h->nx;

} while(h);

return;

}

// функция удаления элемента с головы очереди

void del(zap **t,zap **h)

{ zap *p;

if(*t==*h) // в очереди только один элемент

{ free(*h);

*t=*h=NULL; // очередь пуста

return;

}

p=(*h)->nx;

free(*h); // удаление элемента с головы очереди

*h=p;

}

// функция удаления любого элемента очереди

void del_any(zap **t,zap **h,char *st)

{ zap *p,*pr; // указатели: на анализируемый элемент и

// предыдущий ему элемент очереди

if (*t==*h && // в очереди только один элемент

(!strcmp((*h)->inf,st) || *st=='\0'))

{ free(*t);

*t=*h=NULL; // очередь пуста

return;

}

while( *h && !strcmp((*h)->inf,st)) // удаление всех элементов st

// с головы очереди

{ p=*h; // сохраняем адрес удаляемого элемента

*h=(*h)->nx; // перемещение указателя на голову очереди

// на следующий элемент

free(p); // удаление элемента

}

p=(*h)->nx; // следующий за элементом головы очереди

pr=*h; // элемент перед ним

while(p)

{ if(!strcmp(p->inf,st)) // удаление всех элементов st

// с головы очереди

{ pr->nx=p->nx; // исключение из очереди удаляемого элемента

free(p); // удаление из очереди

p=pr->nx; // переход к анализу следующего эмемента

}

else

{ p=p->nx; // переход к анализу следующего эмемента

pr=pr->nx;

}

}

p=*h;

while(p->nx) p=p->nx; // проход по очереди

*t=p; // коррекция адреса хвоста очереди

}

// функция сортировки содержимого очереди

void sort(zap **h)

{ zap *s1,*s2,*s3,*s4,*hh=NULL;

s1=s3=*h; // ссылка на голову очереди

s4=( zap *) calloc(1,sizeof(zap));

for(; s1->nx; s1=s1->nx) // выбор элемента для упорядочивания

{ for(s2=s1->nx; s2; s3=s3->nx, s2=s2->nx) // перебор последующих элементов

{ if (s2==s1->nx) s3=s1; // S3-элемент расположенный перед S2

if(strcmp(s1->inf,s2->inf)>0) // найдено новое меньшее значение

{ s3->nx=s2->nx;

s2->nx=s1; // элемент с min становится перед S1

s4->nx=s2; // S4- элемент расположенный перед S1

s1=s2; // новый адрес S1- (после замены S1<->S2)

}

}

if(!hh)

{ hh=s1; // модификация текущего указателя на голову очереди

free(s4);

}

s4=s1;

}

*h=hh; // возврат возможно измененного указателя на голову

}