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