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

*first = q;

else (*last)->next = q; *last = q;

}

/* извлечение информации из первого элемента очереди с последующим удалением этой вершины

*/

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

{

ELEMENT *q;

if (*first == NULL) return 0;

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

*first = (*first)->next; if (*first == NULL)

*last = NULL; free(q);

return 1;

}

int main ( )

{

int i, x;

ELEMENT *first = NULL, *last = NULL; for (i = 0; i < 10; i++)

AddElement(&first, &last, i); while (Extract(&first, &last, &x))

printf("x = %d\n", x); return 0;

}

14.5.Задачи на стеки и очереди

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

261

из которых извлекается информация. Также написать функцию удаления стека.

2.Расположить элементы целочисленного массива размером n в обратном порядке с использованием стека.

3.Написать функцию, которая слова в текстовом файле распечатывает в обратном порядке. По файлу можно пройти только один раз.

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

5.Даны две непустые очереди, которые содержат одинаковое количество элементов. Объединить очереди в одну, в которой элементы исходных очередей чередуются.

6.Даны две непустые очереди. Элементы каждой из очередей упорядочены по возрастанию. Объединить очереди в одну с сохранением упорядоченности элементов.

7.Пусть имеется файл действительных чисел и некоторое число C. Используя очередь, напечатать сначала все элементы, меньшие числа C, а затем все остальные элементы.

14.6. Двусвязные списки

Для более гибкой работы с линейными списками каждый элемент можно снабдить дополнительным ссылочным полем, чтобы каждый элемент содержал ссылки на два соседних элемента:

В данном случае упрощается операция добавления и удаления элемента списка, а также можно исследовать список в любом направлении.

262

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

#include<stdio.h>

#include<stdlib.h>

typedef struct ELEMENT

{

int data;

struct ELEMENT *prev, *next; } ELEMENT;

/* создание заглавного элемента списка */ void CreateHead(ELEMENT **head)

{

*head = (ELEMENT *)malloc(sizeof(ELEMENT)); (*head)->prev = (*head)->next = NULL;

}

/* вставка элемента в список с условием упорядоченности*/ void Insert(ELEMENT *head, int x)

{

ELEMENT *q, *t; q = head;

/* ищем позицию для нового элемента со значением x: */ while(q->next != NULL && q->next->data <= x)

q = q->next;

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

t->next = q->next;

if (q->next != NULL) q->next->prev = t;

t->prev = q; q->next = t;

}

263

/* вывод списка на экран: */ void Print(ELEMENT *head)

{

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

{

printf("%d -> ", q->data); q = q->next;

}

putchar('\n');

}

int main()

{

ELEMENT *head; int x; CreateHead(&head);

while(scanf("%d", &x) == 1) Insert(head, x);

Print(head); return 0;

}

14.7.Задачи на двусвязные списки

1.Пусть имеется односвязный список действительных чисел, каждый элемент которого содержит дополнительное (нереализованное) ссылочное поле prev. Преобразовать исходный односвязный список в двусвязный, в котором каждый элемент связан не только с последующим элементом (с помощью поля next), но и с предыдущим (с помощью поля prev).

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

3.Написать функцию, которая, получив в качестве параметра указатель на один из элементов двусвязного списка действи-

264