Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Очередь.docx
Скачиваний:
1
Добавлен:
13.11.2019
Размер:
741.84 Кб
Скачать

1.3 Использование собственного класса gQueue

Используем метод реализации очереди с помощью массива.

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

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

Вы вошли в магазин. В данный момент — вы новый элемент очереди, уже созданный, но не принадлежите очереди. Выбрав товар — подходите к кассе. Становитесь в конец очереди. В этот момент вы — хвост очереди. Очередь постепенно уменьшается. За вами становится еще человек. Теперь он хвост, а вы теперь не крайний. Когда подходит ваша очередь рассчитываться на кассе — вы голова очереди, так как впереди вас никого нет. Если в этот момент сзади вас тоже никого, то вы являетесь и головой и хвостом очереди. Вы рассчитались и покинули очередь. Если за вами кто-то был, теперь он голова очереди. Если нет — очередь пуста.

Рассмотрим пример создания класса, реализующего очередь в среде Visual Studio 2010. Реализовать класс Очередь можно с помощью разных базовых структур. В примере использованы три вида реализации:

  1. На массивах.

  2. На списке.

  3. С помощью организации двунаправленного списка.

Для того, чтобы объединить все три способа реализации в одном проекте используем интерфейс. Интерфейс, так же как и класс, создается с помощью конструктора, встроенного в среду Visual Studio 2010.

Рисунок 1.2 – Добавление класса к проекту

После того, как к проекту был добавлен интерфейс и три реализующих его класса, окно Обозревателя выглядит следующим образом.

Рисунок 1.3 – Состав проекта

Ниже приводится листинг составляющих проекта.

  1. Интерфейс IQueue

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace WinQueue

{

public interface IQueue<T>

{

void Enqueue(T item);

T Dequeue();

int Count { get; }

List<T> ToList();

void Clear();

bool IsEmpty { get; }

T Peek();

}

}

2. Класс MasQuery, реализующий интерфейс IQueue на массивах

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace WinQueue

{

class MasQuery<T>:IQueue<T>

{

T[] arrayElem;

public MasQuery()

{

arrayElem = new T[0];

}

// Очищает очередь

public void Clear()

{

arrayElem = new T[0];

}

// Длина очереди

public int Count

{

get

{

return (int)arrayElem.Length;

}

}

// Удаляет и возвращает объект находящийся в начале очереди.

public T Dequeue()

{

if (IsEmpty) throw new Exception("Queue is empty.");

T r = arrayElem[0];

T[] buf = arrayElem;

arrayElem = new T[arrayElem.Length - 1];

// arrayElem = arrayElem.Skip(1).ToArray();

for (int i = 0; i < arrayElem.Length; i++)

arrayElem[i] = buf[i + 1];

return r;

// arrayElem = arrayElem.Skip(1).ToArray();

}

/// Добавляет элемент в очередь

public void Enqueue(T item)

{

T[] buf = arrayElem;

arrayElem = new T[arrayElem.Length + 1];

for (int i = 0; i < buf.Length; i++)

arrayElem[i] = buf[i];

arrayElem[arrayElem.Length - 1] = item;

}

/// Возвращает, но не удаляет из очереди объект.

public T Peek()

{

return arrayElem[0];

}

public bool IsEmpty

{

get { return Count == 0; }

}

/// Переводит в список

public List<T> ToList()

{

return arrayElem.ToList();

}

}

}

3. Класс MyQueue, реализующий интерфейс IQueue на массивах

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace WinQueue

{

class MyQueue<T>:IQueue<T>

{

private List<T> Data=new List<T>();

public void Enqueue(T item)

{

Data.Add(item);

}

public T Dequeue()

{

if (IsEmpty) throw new Exception("Queue is empty.");

var I = Data[0];

Data.RemoveAt(0);

return I;

}

public int Count

{

get { return Data.Count; }

}

public List<T> ToList()

{

return Data;

}

public void Clear()

{

Data.Clear();

}

public bool IsEmpty

{

get { return Count == 0; }

}

public T Peek()

{

if (IsEmpty) throw new Exception("Queue is empty.");

return Data[0];

}

}

}

4. Класс PQueue, реализующий интерфейс с помощью организации двунаправленного списка

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace WinQueue

{

class PQueue<T>:IQueue<T>

{

private class QueueElement

{

public T Value;

public QueueElement Next;

public QueueElement Prev;

}

private QueueElement Head;

private QueueElement Tail;

public void Enqueue(T item)

{

Count++;

var NewElement=new QueueElement() { Value = item };

if (Head == null)

{

Head = NewElement;

Tail = Head;

}

else

{

Tail.Next = NewElement;

NewElement.Prev = Tail;

Tail = Tail.Next;

}

}

public T Dequeue()

{

if (IsEmpty) throw new Exception("Queue is empty.");

Count--;

var Item = Tail;

Tail = Tail.Prev;

if (Tail == null) Head = null;

else Tail.Next = null;

return Item.Value;

}

public int Count { get; private set; }

public List<T> ToList()

{

List<T> Q = new List<T>();

var Item = Head;

while (Item != null)

{

Q.Add(Item.Value);

Item = Item.Next;

}

return Q;

}

public void Clear()

{

Head = null;

Tail = null;

}

public bool IsEmpty

{

get { return Head == null; }

}

public T Peek()

{

if (IsEmpty) throw new Exception("Queue is empty.");

return Head.Value;

}

}

}

5. Класс Form1, реализующий демострацию использования методов класса.

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace WinQueue

{

public partial class Form1 : Form

{

IQueue<string> Queue;

public Form1()

{

InitializeComponent();

// подключение класса, реализующего интерфейс

Queue = new MasQuery<string>();

}

private void Enqueue_Click(object sender, EventArgs e)

{

Queue.Enqueue(EnqValue.Text);

ResetMainTB();

}

private void button1_Click(object sender, EventArgs e)

{

try

{

MessageBox.Show("Element = " + Queue.Dequeue());

}

catch(Exception E)

{

MessageBox.Show("Exception: "+E.Message);

}

ResetMainTB();

}

private void Clear_Click(object sender, EventArgs e)

{

Queue.Clear();

ResetMainTB();

}

private void Count_Click(object sender, EventArgs e)

{

MessageBox.Show("Count = "+Queue.Count.ToString());

}

private void ResetMainTB()

{

MainTB.Lines = Queue.ToList().ToArray();

}

}

}

Рабочий проект представлен на следующем рисунке.

Рисунок 1.5 – Рабочий проект

При решении своего варианта лабораторной работы можно воспользоваться любым описанным способом реализации очереди или создать собственный.