Задание
Написать программу, в которой сначала данные (например, текстовые строки) заносится в список типа I, после чего другие данные того же типа заносятся в список типа II. Затем в список типа III заносятся данные из предыдущих двух списков по принципу IV.
Списки типа I и II могут принимать значения:
A – стек
B – очередь
C – линейный однонаправленный список
Признак конца ввода списка (для текстовых строк) должно быть слово «END». Для стека и очереди предусмотреть обработку ключевого слова «DEL» - извлечение последнего введенного элемента из стека/очереди и, соответственно, его удаление. Предусмотреть случай пустого стека/очереди.
Список типа III может быть следующих видов:
A – линейный двунаправленный список (каждый элемент которого содержит поля next и prev).
B – линейный однонаправленный отсортированный список (в порядке возрастания значения элементов списка)
Список типа A вывести два раза: в прямой и обратной последовательности.
Принцип (IV) построения списка:
A - все данные должны быть в единственном экземпляре
B - при попытке вставить запись, которая уже существует, удалять существующую запись из формирующегося списка (то есть данные должны присутствовать в списке, если они в исходных списках присутствовали нечетное количество раз).
C - вставляются все данные (с повторами), но элементы первого списка вставляются в конец, а элементы второго списка – в начало результирующего списка.
D - вставляются все данные (с повторами), но когда встречается повтор, то переносить такие элементы в конец списка. То есть сначала должны идти данные без повторов (отсортированные или нет, в зависимости от типа списка III), затем повторяющиеся.
Варианты заданий
№ |
I |
II |
III |
IV |
1 |
A |
B |
A |
B |
2 |
A |
C |
A |
C |
3 |
B |
C |
A |
D |
4 |
A |
B |
A |
C |
5 |
A |
C |
A |
D |
6 |
B |
C |
A |
B |
7 |
A |
B |
A |
D |
8 |
A |
C |
A |
B |
9 |
B |
C |
A |
C |
10 |
A |
B |
B |
B |
11 |
A |
C |
B |
A |
12 |
B |
C |
B |
D |
13 |
A |
B |
B |
A |
14 |
A |
C |
B |
D |
15 |
B |
C |
B |
B |
16 |
A |
B |
B |
D |
17 |
A |
C |
B |
B |
18 |
B |
C |
B |
A |
19 |
A |
B |
A |
A* |
20 |
A |
C |
A |
A* |
Пример программы.
Написать программу, демонстрирующую работу с двунаправленным линейным отсортированным списком (в качестве данных использовать тип int). Необходимо обеспечить ввод и вывод списка. В качестве признака окончания ввода данных использовать значение 0.
#include<conio.h>
#include<stdio.h>
#include<alloc.h>
typedef struct _TLIST
{
int data;
struct _TLIST *prev;
struct _TLIST *next;
}TLIST;
// Функция вставки элемента списка перед текущим элементом
int AddItemBeforeCurrent( TLIST **head, TLIST *current, int data )
{
TLIST *newItem = (TLIST*)malloc(sizeof(TLIST));
if ( !newItem )
return -1;
newItem->data = data;
if ( current ) // В списке уже есть элементы
{
newItem->prev = current->prev;
newItem->next = current;
if ( !current->prev ) // Текущий элемент – первый в списке
*head = newItem;
else
current->prev->next = newItem;
current->prev = newItem;
}
else // Список еще пустой
{
*head = newItem;
newItem->prev = NULL;
newItem->next = NULL;
}
return 0;
}
// Функция вставки элемента списка после текущего элемента
int AddItemAfterCurrent( TLIST **head, TLIST *current, int data )
{
TLIST *newItem = (TLIST*)malloc(sizeof(TLIST));
if ( !newItem )
return -1;
newItem->data = data;
if ( current ) // В списке уже есть элементы
{
newItem->prev = current;
newItem->next = current->next;
if ( current->next ) // Текущий элемент – не последний
current->next->prev = newItem;
current->next = newItem;
}
else // Список еще пустой
{
*head = newItem;
newItem->prev = NULL;
newItem->next = NULL;
}
return 0;
}
// Функция вставки элемента списка с учетом сортировки по возрастанию
int InsertIntoSortList( TLIST **head, int data )
{
TLIST *current = *head, *last=NULL;
// Ищем элемент перед которым можно вставить новую запись
while( current && current->data<data )
{
last = current;
current = current->next;
}
if ( current ) // Такой элемент найден
return AddItemBeforeCurrent( head, current, data );
else
return AddItemAfterCurrent( head, last, data );
}
// Функция печати списка
void PrintList( TLIST *head )
{
TLIST *current = head;
while( current )
{
printf("%d\n", current->data);
current = current->next;
}
}
// Функция удаления списка
void DeleteList( TLIST **head )
{
TLIST *next;
while(*head)
{
next = (*head)->next;
free(head);
*head = next;
}
}
// Функция ввода списка
int InputList( TLIST **head )
{
int data, stat=0;
while( 1 )
{
printf("Введите очередной элемент: ");
scanf("%d", &data);
if ( data==0 )
break;
stat = InsertIntoSortList( head, data );
if ( stat )
{
// Произошла ошибка. Удаляем сформированный ранее список
// и выходим.
DeleteList(head);
break;
}
}
return stat;
}
void main(void)
{
int stat;
TLIST *head = NULL;
clrscr();
stat = InputList( &head );
if ( !stat )
PrintList( head );
else
printf("Ошибка работы с памятью");
getch();
if ( !stat )
DeleteList( &head );
}
* Перед выводом результирующего списка (типа III), удалить в нем все четные элементы