- •Основы алгоритмизации и программирования, язык Си
- •Введение
- •Блок-схема алгоритма Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Операции и выражения
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора Директива #include
- •Директива #define
- •Понятие пустого и составного операторов
- •Условные операторы
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Операторы перехода (break, continue, return, goto)
- •Примеры программ
- •Массивы Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Параметры по умолчанию
- •Передача массива в функцию
- •Inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Доступ к элементам структуры
- •Инициализация структур
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Примеры программ
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Потоки и файлы
- •Файлы Основные сведения о файловой системе
- •Организация посимвольного ввода и вывода
- •Определение конца файла feof()
- •Организация ввода и вывода строк
- •Удаление файлов
- •Дозапись потока
- •Позиционирование в файле
- •Текстовые и двоичные файлы
- •Функции fread() и fwrite()
- •Примеры программ
- •Хеширование
- •Схемы хеширования
- •Метод открытой адресации с линейным опробыванием
- •Метод цепочек
- •Машинное представление графов
- •Примеры программ
- •Литература
Односвязный линейный список, очередь
Односвязный список (очередь) - такая упорядоченная структура данных, которые могут удаляться с одного ее конца (начало очереди ), а добавляются в другой ее конец (конец очереди).
Очередь организована по принципу 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; // возврат возможно измененного указателя на голову
}