顺序队列(Sequence Queue)用一片连续的存储空间来存储队列中的数据元素. 用一维数组来存放顺序队列中的数据元素。 队头位置设在数组下标为 0 的端,用 front 表示; 队尾位置设在数组的另一端,用 rear 表示。 front 和 rear 随着插入和删除而变化。 当队列为空时, front=rear=0。 因为在出队列(删除元素)的时候,需要花费大量 的时间移动大量元素,速度很慢,所以很少有实际 应用。
循环顺序队列,为了避免大量数据的移动,通常将一维数组的各个元素看成一个收尾相接的封闭的圆环,即第一个元素是最后一个元素的下一个元素,这种形式的顺序队列成为循环顺序队列(Circular sequence Queue)。 C#为我们提供的Queue类就是循环队列。
namespace 队列
{
/// <summary>
/// 链队列的 节点类
/// </summary>
/// <typeparam name="T"></typeparam>
class QueueNode<T>
{
public T data;
public QueueNode<T> next;
public QueueNode(T _data) {
this.data = _data;
}
public override string ToString()
{
return data.ToString();
}
}
}
namespace 队列
{
interface IQueueDS<T>
{
int Count { get; }//获取元素个数
int GetLength();
bool IsEmpty(); //是否为空队列
void Clear(); //清空队列
void Enqueue(T item); //入队
T Dequeue(); //出队
T Peek(); //取队头元素
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 队列
{
/// <summary>
/// 顺序循环队列
/// </summary>
/// <typeparam name="T"></typeparam>
class CSeqQueue<T> : IQueueDS<T>
{
//存放元素的数组
public T[] _array;
//增长因子 1-10之间
private int _growfactor;
//最小增长值
private const int _MinimumGrow = 4;
//默认队列空间的大小
private const int _defaultCapacity = 8;
//元素的个数
private int _size = 0;
//队头指针 指向队头的第一个元素
private int _head;
//队尾指针 指向队尾的最后一个元素索引+1
private int _tail;
public CSeqQueue() : this(_defaultCapacity,2){ }
public CSeqQueue(int capacity, float growFactor) {
if (capacity < 0) {
throw new ArgumentOutOfRangeException("capacity","初识容量不能小于0");
}
if (capacity < _defaultCapacity) {
capacity = _defaultCapacity;
}
if (growFactor < 1.0 || growFactor > 10.0) {
throw new ArgumentOutOfRangeException("growFactor","增长因子必须在1-10之间");
}
this._array = new T[capacity]; //初始化数组
this._head = this._tail = 0;
this._size = 0;
this._growfactor = (int)(growFactor * 100f);
}
//获取元素个数
public int Count {
get {
return this._size;
}
}
public void Clear()
{
this._head = this._tail = this._size = 0;
}
//出队操作
public T Dequeue()
{
if (this._size == 0)
{
throw new InvalidOperationException("队列下溢,队里里没有数据");
}
T obj = this._array[_head]; //出队数据
this._array[_head] = default(T); //在数组里删除出队元素
this._head = (this._head + 1) % this._array.Length; //循环队列 处理机制,保证下标是循环的
this._size--;
return obj;
}
//入队
public void Enqueue(T item)
{
if (this._size == this._array.Length) {
//计算新的容量
int capacity = (int)(this._array.Length * this._growfactor / 100f);
if (capacity < this._array.Length + _MinimumGrow) {
//最少要增长四个元素
capacity = this._array.Length + _MinimumGrow;
}
//调整容量
SetCapacity(capacity);
}
this._array[_tail] = item; //入队
this._tail = (this._tail + 1) % this._array.Length; //移动尾巴指针
this._size++;
}
private void SetCapacity(int capacity) { //内存搬家
T[] destinationArray = new T[capacity];
if (this._head < this._tail)
{
//头指针在尾指针的前面
Array.Copy(this._array, this._head, destinationArray, 0, this._size);
}
else {
//头指针在尾指针的后面
Array.Copy(this._array, this._head, destinationArray, 0, this._array.Length-this._head);
Array.Copy(this._array, 0, destinationArray, this._array.Length - this._head, this._tail);
}
this._array = destinationArray;
this._head = 0;
this._tail = (this._size == capacity) ? 0 : this._size;
}
public int GetLength()
{
return this._size;
}
public bool IsEmpty()
{
return this._size == 0;
}
//获取队头元素,不删除
public T Peek()
{
if (this._size == 0) {
throw new InvalidOperationException("队列下溢,队里里没有数据");
}
T obj = this._array[_head]; //出队数据
return obj;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 队列
{
class Program
{
static void Main(string[] args)
{
//创建一个队列对象
//Queue<int> queue = new Queue<int>();
//创建一个循环顺序列表
IQueueDS<int> queue = new CSeqQueue<int>();
////创建一个链队列
//IQueueDS<int> queue = new LinkedQueue<int>();
queue.Enqueue(10); //入队操作, 队头位置
queue.Enqueue(20);
queue.Enqueue(30);
queue.Enqueue(40); //队尾
Console.WriteLine("入队数据是 10,20,30,40,队列元素个数为 :"+queue.Count);
int dq = queue.Dequeue(); //出队,返回出队数据
Console.WriteLine("Dequeue 出队操作,数据为:"+dq+",队列元素个数为: "+queue.Count);
int pk = queue.Peek();//只获取队头数据,不做出队操作
Console.WriteLine("Peek 获取数据为:" + pk + ",队列元素个数为: " + queue.Count);
queue.Clear(); //清空队列
Console.WriteLine("Clear 清空操作,队列元素个数为: " + queue.Count);
Console.WriteLine("=================================华丽分割线====================================");
IQueueDS<string> cQueue = new CSeqQueue<string>();
for (int i = 1; i < 8; i++)
{
cQueue.Enqueue("a"+i); //1,2
}
for (int i = 0; i < 4; i++)
{
cQueue.Dequeue();
}
for (int i = 8; i < 13; i++)
{
cQueue.Enqueue("a" + i); //efg
}
for (int i = 0; i < 4; i++)
{
cQueue.Dequeue();
}
Console.WriteLine("cQueue 获取数据为:" + cQueue.Peek() + ",队列元素个数为: " + cQueue.Count);
Console.ReadKey();
}
}
}
来源:CSDN
作者:a592733740
链接:https://blog.csdn.net/a592733740/article/details/104804725