Лабораторная работа №2. Использование структуры Очередь
1.1 Понятие очереди
Очередь (queue) — это коллекция, в которой элементы обрабатываются по схеме "первый вошел, первый вышел" (first in, first out — FIFO). Элемент, вставленный в очередь первым, первым же и читается. Примерами очередей могут служить очередь в аэропорту, очередь претендентов на трудоустройство, очередь печати принтера либо циклическая очередь потоков на выделение ресурсов процессора. Часто встречаются очереди, в которых элементы обрабатываются по-разному, в соответствии с приоритетом.
Рисунок 1.1 – Структура Очередь
Над очередью можно выполнять такие операции:
– инициализация (Init);
– деструктизация (Destroy);
– помещение элемента в очередь (Insert);
– удаление элемента из очереди (Remove);
– значение первого элемента (Head);
– значение последнего элемента (Tail);
– проверка на пустоту (isEmpty);
– проверка на полноту (isFull)
1.2 Использование класса .Net Queue
В .NET имеется необобщенный класс Queue в пространстве имен System. Collection и обобщенный класс Queue<T> в пространстве имен System.Collections.Generic. Оба класса очень похожи по своей функциональности, за исключением того, что обобщенный класс строго типизирован, определяя тип Т, а необобщенный класс основан на типе Object. Внутри класс Queue<T> использует массив типа Т,
Очередь реализуется с помощью классов Queue из пространства имен System.Collections и Queue<T> из пространства имен System.Collections.Generic.
В классе Queue существуют два основных метода работы с элементами очереди:
Enqueue() - помещает элемент в конец очереди;
Dequeue() - достает из очереди первый элемент.
В принципе этого вполне достаточно. У класса Queue есть еще несколько полезных методов:
Contains() - проверяет имеется ли данный объект в очереди;
Count - свойство, содержащее количество элементов в очереди;
Peek() - возвращает первый элемент в очереди, но не удаляет его.
Рассмотрим пример:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace Query2
{
class Program
{
static void Main(string[] args)
{
Queue q = new Queue();
q.Enqueue(2); //помещаем в очередь двойку
q.Enqueue(3); //помещаем в очередь тройку
q.Enqueue(5); //помещаем в очередь пятерку
//наша очередь выглядит так: 5 3 2
Console.WriteLine("В очереди содержится " + q.Count + "
объекта"); //выведет 3
Console.WriteLine("Первый элемент: " + q.Peek()); //выведет 2
Console.WriteLine Console.WriteLine(((int)q.Dequeue() +
(int)q.Dequeue()) * (int)q.Dequeue()); //2+3*5
Console.ReadKey(true);
}
}
}
Сперва мы создаем экземпляр класса Queue. После чего помещаем в очередь 3 элемента. В нашем случае это объекты типа int. Обратите внимание на очередность. Двойка заняла очередь первой, а пятерка последней. Далее мы узнаем, сколько элементов содержится в очереди. Узнаем, кто первый. Ну а далее мы извлекаем элементы из очереди и сразу выполняем расчеты. Приведение к типу int обязательно, т.к. в очереди хранятся объекты типа object вне зависимости от того, что в очередь было помещено.
Нужно помнить, что невозможно узнать, кто в очереди второй или третий, пока не "достать" из очереди соответствующее количество элементов.
Очередь не является типизированной, т.е. в ней могут содержаться объекты разных типов. Т.е. если мы сделаем так:
q.Enqueue("строка"); //помещаем в очередь строку
q.Enqueue(3); //помещаем в очередь тройку
q.Enqueue(4); //помещаем в очередь четверку
q.Enqueue(5); //помещаем в очередь пятерку,
то программа "вылетит" с ошибкой, при попытке приведения типов.
Таблица 1.1 Члены классов Queue и Queue<T>
Enqueue() |
МетодEnqueue () добавляет элемент в конец очереди. |
Dequeue ()
|
МетодDequeue () читает и удаляет элемент из головы очереди. Если в очереди больше нет элементов на момент вызова метода Dequeue (), генерируется исключение InvalidOperationException. |
Peek() |
МетодPeek () читает элемент из головы очереди, но не удаляет его. |
Count |
СвойствоCountвозвращает количество элементов в очереди. |
TrimExcess()
|
TrimExcess () изменяет емкость очереди. МетодDequeue () удаляет элемент из очереди, но не изменяет ее емкости. Чтобы избавиться от пустых элементов в начале очереди, используйте методTrimExcess (). |
Contains ()
|
МетодContains () проверяет наличие элемента! в очереди и возвращает true,если искомый элемент в ней содержится. |
СоруТо () |
С помощью метода СоруТо () вы можете копировать элементы очереди в существующий массив. |
ToArray()
|
Метод ToArray () возвращает новый массив, содержащий элементы очереди. |
Рассмотрим еще несколько примеров, использующих Queue.
Пример 1. Перебор элементов очереди.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Queue<int> fifo = new Queue<int>(); fifo.Enqueue(1); fifo.Enqueue(2); fifo.Enqueue(3); fifo.Enqueue(4); fifo.Enqueue(5); Console.WriteLine("Первый элемен очереди {0}", fifo.Peek()); Console.WriteLine("Опять он первый {0}", fifo.Peek()); // А теперь Обрабатываем и удаляем из очереди for (int i = 0; i < 5; i++) { Console.WriteLine("Элементов в очереди {0}", fifo.Count); Console.WriteLine("Первый элемен очереди {0}", fifo.Dequeue()); }
Console.ReadKey(true);
} } }
Пример 2. Заполнение очереди случайными числами.
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
Queue qe = new Queue<int>();
Random ran = new Random();
for (int i = 0; i < 10; i++)
qe.Enqueue(ran.Next(1, 10));
Console.WriteLine("Очередь: \n");
foreach (int i in qe)
Console. Write(i + "\t");
Console.ReadLine();
}
}
}
Пример 3. Передача очереди в качестве аргумента процедуры.
using System;
using System.Collections;
public class SamplesQueue {
public static void Main() {
// Creates and initializes a new Queue.
Queue myQ = new Queue();
myQ.Enqueue("Hello");
myQ.Enqueue("World");
myQ.Enqueue("!");
// Displays the properties and values of the Queue.
Console.WriteLine( "myQ" );
Console.WriteLine( "\tCount: {0}", myQ.Count );
Console.Write( "\tValues:" );
PrintValues( myQ );
}
public static void PrintValues( IEnumerable myCollection ) {
foreach ( Object obj in myCollection )
Console.Write( " {0}", obj );
Console.ReadKey();
}
}