Просмотр и анализ списка целых чисел

За один просмотр выведем на экран и найдём количество отрицательных чисел в списке, созданном в 2.1.

В этом случае в начале списка есть фиктивный элемент. Так как он при просмотре не должен участвовать (фиктивный элемент не выводим и не анализируем), то переходим на второй элемент списка, то есть на первый реальный:

Q=P->next;

Напомним, что в переменной P находится адрес начала списка, то есть в нашем случае для первого списка адрес фиктивного элемента. Заметим, что при работе с обычным одномерным числовым массивом (не полем списка), объявленного, например, так:

const n=10; int a[n];

это соответствует заданию начального значения индекса одномерного массива, например: i=0;.

Как и при работе с одномерным массивом, цикл можно организовать разными способами.

Условие выхода из цикла можно записать так:

while (Q) …;,

или, что то же самое,

while (Q!=NULL)…;.

Цикл будет выполняться, пока в Q не поместим значение адресного поля последнего “правого” элемента списка, равное NULL, то есть пока не достигнем конца списка. При работе с массивом это частично напоминает оператор цикла while (i<n)…;.

Кроме такого цикла, как и при работе с массивом, можно записать цикл со счётчиком

for (int i=1; i<=n; i++)

где n —количество реальных (без фиктивного) элементов списка (в нашем примере целых чисел). Но в таком случае переменная (или константа) n должна быть объявлена как глобальная или передаваться в функцию просмотра как параметр. Кроме этого, при удалении или вставке элементов n должна быть только переменной и её надо не забыть изменить, сооответсвенно уменьшить или увеличить.

Можно использовать так называемый “вечный” цикл типа while (1), внутри которого записываем условие выхода из него и оператор break.

Внутри цикла используем информационную часть, в примере это одно число, которое обозначается Q->num. Если продолжить сравнение с одномерным массивом, то это чем то напоминает элемент списка a[i]. Для вывода на экран записываем

cout<<Q->num<<" ";.

Здесь же в цикле вместо вывода или вместе с ним может быть анализ одного или нескольких полей информационной части. Например, при работе с нашим списком для нахождения количества отрицательных чисел можно записать:

if (Q->num<0) count1++;

Для более сложного анализа одного числа из списка может понадобиться логическая функция, которая возвращает true или false, в зависимости от того, удовлетворяет ли число некоторому условию (например, является ли оно простым). Такую функцию можно составить и для нашей простой задачи:

bool Analis (int elem) {return elem<0;};

Обратим внимание на то, что из описания функции никак не видно, что она используется для работы с полем списка, то есть в ней нигде не используется ни Q->num, ни

Q->next->num. Это учитывается при вызове,который записываем, например, так:

if (Analis (Q-> num)) count1++;

Для перехода на следующий элемент списка необходимо выполнить оператор присваивания Q=Q->next;. Синтаксически он правильный, так как адрес элемента списка может находиться как в переменной Q, так и в адресном поле элемента списка (см. 1.1). С помощью этого оператора значение адресного поля (а там находится адрес следующего элемента) заносится в переменную-указатель Q. Если сравнивать с массивом, это равносильно увеличению индекса его элемента на единицу, то есть i++;. Заметим, что этот оператор продвижения по списку не зависит от информационной части его элемента.

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

bool Analis (int elem) {return elem<0;};

void LOOK (int &count)

{

count=0;

Q=P->next; // Переход на первый реальный элемент списка

while (Q)

{ cout<<Q->num<<" "; // Вывод информационной части

if (Analis (Q->num)) count++; // Анализ информационной части

Q=Q->next; // Переход на следующий элемент

}

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: