Использование собственного класса 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; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!