- •Основы алгоритмизации и программирования, язык Си
- •Введение
- •Блок-схема алгоритма Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Операции и выражения
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора Директива #include
- •Директива #define
- •Понятие пустого и составного операторов
- •Условные операторы
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Операторы перехода (break, continue, return, goto)
- •Примеры программ
- •Массивы Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Параметры по умолчанию
- •Передача массива в функцию
- •Inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Доступ к элементам структуры
- •Инициализация структур
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Примеры программ
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Потоки и файлы
- •Файлы Основные сведения о файловой системе
- •Организация посимвольного ввода и вывода
- •Определение конца файла feof()
- •Организация ввода и вывода строк
- •Удаление файлов
- •Дозапись потока
- •Позиционирование в файле
- •Текстовые и двоичные файлы
- •Функции fread() и fwrite()
- •Примеры программ
- •Хеширование
- •Схемы хеширования
- •Метод открытой адресации с линейным опробыванием
- •Метод цепочек
- •Машинное представление графов
- •Примеры программ
- •Литература
Циклический список, кольцо
Связанное хранение линейного списка называется циклическим списком или кольцом, если его последний элемент указывает на первый элемент списка, а указатель на список - на последний элемент списка (см. рис. 17).
Рис.17. Схема циклического хранения списка.
Двусвязный циклический список
Как и в случае линейного списка, элементы циклического списка могут иметь несколько ссылок. Текст программы, иллюстрирующий работу с двунаправленным циклическим списком, приведен ниже.
#include <stdio.h>
#include <alloc.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
struct zap
{ char inf[50];
zap *l,*r;
};
void see(zap *);
zap *sozd(zap *);
zap *del(zap *);
void srt(zap *);
zap *srt_uk(zap *);
zap * napr(char,zap *);
void main(void)
{ zap *s=NULL;
char l;
clrscr();
while(1)
{ puts("вид операции: 1-создать кольцо");
puts(" 2-вывод содержимого кольца");
puts(" 3-удаление элемента из кольца");
puts(" 4-сортировка (изменяя указатели на элементы)");
puts(" 5-сортировка (изменяя содержимое элементов)");
puts(" 0-выход");
fflush(stdin);
switch(getch())
{ case '1': s=sozd(s); break;
case '2': if(s) see(s);
else puts("Кольцо пустое"); getch(); break;
case '3': if(s) s=del(s); break;
case '4': if(s) s=srt_uk(s); break;
case '5': if(s) srt(s); break;
case '0': return;
}
clrscr();
}
}
// функция создания/добавления в кольцо
// добавление выполняется вправо от элемента входа в кольцо
zap *sozd(zap *s)
{ zap *s1,*s2;
if (!s)
{ if(!(s=(zap *) malloc(sizeof(zap))))
{ puts("Нет свободной памяти");
return NULL;
}
puts("Введите информацию в inf");
scanf("%s",s->inf);
s->l=s;
s->r=s;
s1=s;
}
else s1=s->r; // кольцо уже существует
do
{ if((s2=(zap *) calloc(1,sizeof(zap)))==NULL)
{ puts("Нет свободной памяти");
return NULL;
}
puts("Введите информацию в inf");
scanf("%s",s2->inf);
s1->l=s2;
s2->r=s1;
s1=s2;
puts("Продолжить (y/n): ");
fflush(stdin);
} while(getch()=='y');
s2->l=s;
s->r=s2;
return(s);
}
// функция вывода содержимого кольца
void see(zap *s)
{ zap *s1;
char p;
s1=s;
puts("r - по часовой, l - против часовой\n");
fflush(stdin);
switch(p=getch())
{ case 'r': case 'R':
case 'l': case 'L':
do
{ printf("%s\n",s1->inf);
s1=napr(p,s1);
} while(s1!=s); break;
}
puts("Вывод кольца закончен");
return;
}
// функция удаления элемента кольца
zap *del(zap *s)
{ zap *s1;
char in[50];
s1=s;
puts("Введите информацию в inf");
scanf("%s",in);
do
{ if(strcmp(s1->inf,in)) s1=s1->r;
else
{ if (s1->r==s1) // элемент в кольце один
{ free(s1); return NULL; }
if(s==s1) s=s->r; // удаляемый эл-т - точка входа
s1->l->r=s1->r; // исключаем вершину из кольца
s1->r->l=s1->l;
free(s1);
return s;
}
} while(s1!=s);
printf("Записи с информацией = %s в кольце нет \n",in);
getch();
// return s;
}
// сортировка информации в кольце
void srt(zap *s)
{zap *s1,*s2;
char a[50],c;
int i;
puts("направление r - по часовой, l - против часовой\n");
fflush(stdin);
c=getch();
s1=s; // исходный элемент для замены
do
{ strcpy(a,s1->inf); // исходная информ. для замены
s2=s1;
do
{ s2=napr(c,s2); //
if(strcmp(a,s2->inf)>0)
{ strcpy(s1->inf,s2->inf);
strcpy(s2->inf,a);
strcpy(a,s1->inf);
}
} while(napr(c,s2)!=s);
s1=napr(c,s1);;
} while(napr(c,s1)!=s);
}
// сортировка информации в кольце (методом "отбора")
// рассмотрен только случай сортировки вправо (по возрастанию)
zap * srt_uk(zap *s)
{ zap *s1,*s2,*s3;
int i;
s1=s;
do
{ s2=s1->r; s3=s1; // s3 адрес элемента кольца с min значением
do // блок отбора меньшего (его адрес в s3)
{ if(strcmp(s3->inf,s2->inf)>0)
s3=s2; // s3 премещаем на узел с меньшей строкой
s2=s2->r; // поиск далее по кольцу
} while(s2!=s); // пока не прошли по кольцу
if(s3!=s1)
{ if(s==s1) s=s3; // новая точка входа в кольцо
s3->l->r=s3->r; // исключение элемента s3
s3->r->l=s3->l; // из кольца
s1->l->r=s3; // вставляем
s3->r=s1; // элемент s3
s3->l=s1->l; // перед
s1->l=s3; // s1
}
else
s1=s1->r;
} while(s1->r!=s);
return s;
}
zap * napr(char c,zap * s)
{ switch(c)
{ case 'r': case 'R': return s->r;
case 'l': case 'L': return s->l;
}
}