Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Рацеев С.М. Программирование на языке Си.pdf
Скачиваний:
366
Добавлен:
23.03.2016
Размер:
1.65 Mб
Скачать

{

ELEMENT *q, *t; q = head->next; while (q != NULL)

{

t = q;

q = q->next; free(t);

}

head->next = NULL; *last = head;

}

int main()

{

ELEMENT *head, *last; WORKER worker; CreateHead(&head, &last); printf("name: "); scanf("%s", worker.name);

while (strcmp(worker.name, "000"))

{

printf("year: "); scanf("%d", &worker.year); printf("earnings: ");

scanf("%f", &worker.earnings); AddElement(&last, &worker); printf("name: ");

scanf("%s", worker.name);

}

Print(head); Distruct(head, &last); return 0;

}

14.3. Задачи на односвязные списки

255

1.Найти количество максимальных элементов списка действительных чисел.

2.Написать функцию, которая по списку L строит два новых

списка: L1 – из положительных элементов и L2 – из отрицательных элементов списка L.

3.Определить, является ли список упорядоченным по возрастанию.

4.Сформировать список целых чисел, вводимых пользователем, в том порядке, в котором вводятся эти числа, но без повторений элементов.

5.Написать функцию, которая оставляет в списке L только первые вхождения одинаковых элементов.

6.Определить количество различных элементов списка действительных чисел, если известно, что его элементы образуют возрастающую последовательность.

7.Имеется список целых чисел. Продублировать в нем все четные числа.

8.Написать функцию, которая по двум данным линейным спискам формирует новый список, состоящий из элементов, одновременно входящих в оба данных списка.

9.Написать функцию, которая по двум линейным спискам L1 и L2 формирует новый список L, состоящий из элементов, входящих в L1, но не входящих в L2.

10.Написать функцию, которая в линейном списке из каждой группы подряд идущих одинаковых элементов оставляет только один.

11.Написать функцию, которая удаляет из списка элементы, входящие в него только один раз.

12.Пусть имеется список L1 действительных чисел. Записать в список L2 все элементы списка L1 в порядке возрастания их значений.

13.Пусть имеется список действительных чисел a1a2→...→aп. Сформировать новый список b1b2→...→bп такой же размерности по следующему правилу: элемент bk равен сумме элементов исходного списка с номерами от 1 до k.

256

Задачи для самостоятельной работы

14.Написать функцию, которая, получив в качестве параметра указатель q на один из элементов списка и некоторое число x, добавляет новый элемент со значением x после (до) элемента, на который указывает ссылка q.

15.Написать функцию, которая, получив в качестве параметра указатель q на один из элементов списка, удаляет элемент, расположенный после элемента (сам элемент), на который указывает ссылка q.

16.Сформировать список действительных чисел. Затем преобразовать его, прибавив к положительным числам максимальный элемент.

17.Удалить из списка все элементы, встречающиеся более одного раза.

18.Дан список целых чисел. Продублировать в нем все простые числа.

19.Определить, есть ли в списке действительных чисел элементы, превосходящие сумму всех элементов списка.

20.Определить, образуют ли элементы списка действительных чисел геометрическую прогрессию.

21.Удалить из списка действительных чисел все максимальные элементы.

22.Пусть имеются два списка, элементы которых упорядочены по возрастанию. Сформировать новый список из элементов первого и второго списка, элементы которого будут упорядочены.

23.Сформировать список действительных чисел a1a2→...→aп, вводимых пользователем. Затем сформировать новый список

b1b2→...→bп такой же размерности по следующему правилу: элемент bk является максимальным из элементов исходного списка с номерами от 1 до k.

24.Пусть имеется текстовый файл. Используя линейный список, подсчитать число появлений каждого слова и создать новый текстовый файл, каждая строка которого имеет вид "<слово>– <число его появлений>". Слова должны располагаться в лексикографическом порядке.

257

25.Циклический список – это список, последний элемент которого указывает на первый. Такой список позволяет программе снова и снова просматривать его по кругу до тех пор, пока в этом есть необходимость. Написать функцию добавления элемента в циклический список и функцию печати всех элементов списка, начиная с некоторого элемента.

26.Записать в циклический список n целых чисел, вводимых пользователем. Также написать функцию, которая получает в качестве параметров указатель на один из элементов списка q и целое число k > 0. Данная функция пробегает по элементам списка, начиная с элемента q, и останавливается на k-м по счету элементе, который удаляется, и счет начинается со следующего элемента, и так до тех пор, пока в списке не останется один элемент. Функция возвращает значение данного элемента.

14.4. Стеки, очереди

Стеком называется конечный упорядоченный набор элементов, расположенных в динамической памяти, в котором добавление новых элементов и удаление существующих выполняется только с одного его конца, который называется вершиной стека.

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

1)добавление в стек нового элемента;

2)доступ к последнему включенному элементу (вершине стека);

3)исключение из стека последнего включенного элемента. Стеки очень часто используются компиляторами для отсле-

живания функций и их параметров. Всякий раз, когда происходит вызов функции, данная функция должна знать, как вернуться к вызывающей функции, поэтому адрес возврата помещается в стек. Если происходит целый ряд последовательных вызовов, то адреса возврата помещаются в стеке в таком порядке: последним пришел – первым вышел, так что после завершения выполнения каждой функции происходит переход к функции, ее вызвавшей.

258

Пример 1. В следующем примере создается стек, и его с о- держимое выводится на экран, причем после извлечения информации из очередного элемента стека данный элемент удаляется.

#include<stdio.h>

#include<stdlib.h>

typedef struct ELEMENT

{

int data;

struct ELEMENT *next; } ELEMENT;

/* добавление элемента в вершину стека */ void Push(ELEMENT **first, int x)

{

ELEMENT *q;

q = (ELEMENT *)malloc(sizeof(ELEMENT)); q->data = x;

q->next = *first; *first = q;

}

/* Извлечение информации из вершины стека с последующим удалением этой вершины. Информация из вершины стека first помещается в элемент x, а вершина удаляется.

*/

int Extract(ELEMENT **first, int *x)

{

ELEMENT *q;

if (*first == NULL) return 0;

*x = (*first)->data; q = *first;

*first = (*first)->next; free(q);

return 1;

}

259

int main ( )

{

ELEMENT *first = NULL; /* вершина стека */ int i, x;

for (i = 0; i < 10; i++) Push(&first, i);

while (Extract(&first, &x)) printf("x = %d\n", x);

return 0;

}

Другим специальным видом линейного односвязного списка является очередь. Над очередью выполняются следующие операции:

1)добавление в конец очереди нового элемента;

2)доступ к первому элементу очереди;

3)исключение из очереди первого элемента.

Пример 2. Создадим очередь из целых чисел и ее содержимое выведем на экран, причем после извлечения информации из очередного элемента очереди данный элемент удалим.

#include<stdio.h>

#include<stdlib.h>

typedef struct ELEMENT

{

int data;

struct ELEMENT *next; } ELEMENT;

/* добавление элемента в конец очереди */

void AddElement(ELEMENT **first, ELEMENT **last, int x)

{

ELEMENT *q;

q = (ELEMENT *)malloc(sizeof(ELEMENT)); q->data = x;

q->next = NULL; if (*last == NULL)

260