Использование собственного класса 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 – Рабочий проект

 

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


Дата добавления: 2015-12-21; просмотров: 13; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!