一. 顺序队列
在顺序队列中,我们维护一个头指针和尾指针来避免每一次出队都要移动数组,而仅仅在入队时发现空间不足时,在尝试进行移动数组操作,将空余的位置利用起来。
public class MyQueue<T> { T[] data; // 数据 int front = 0; // 前指针 int rear = 0; // 后指针 public MyQueue(int size) { data = new T[size]; } /// <summary> /// 入队 /// </summary> /// <param name="model"></param> public void Enqueue(T model) { if (rear < data.Length) data[rear] = model; else { if (front > 0) { Move(); data[rear] = model; } else throw new ArgumentOutOfRangeException("超出队列长度"); } rear++; } /// <summary> /// 出队 /// </summary> /// <returns></returns> public T Dequeue() { T result = default(T); if (rear > front) result = data[front]; else throw new NullReferenceException("队列中没有值"); front++; return result; } public bool IsEmpty() { return front == rear; } public bool IsFull() { return rear == data.Length; } public int Length => data.Length; public int ItemLength => rear - front; private void Move() { var itemlength = ItemLength; // 移动队列,将下标为0的前数组填满 for (int i = 0; i < itemlength; i++) { data[i] = data[front]; front++; } front = 0; rear = itemlength; }
测试代码:
1 try 2 { 3 MyQueue<int> queue = new MyQueue<int>(3); 4 queue.Enqueue(1); 5 queue.Enqueue(2); 6 queue.Enqueue(3); 7 for (int i = 0; i < queue.Length; i++) 8 { 9 Console.WriteLine(queue.Dequeue()); 10 } 11 queue.Enqueue(4); 12 queue.Enqueue(5); 13 queue.Enqueue(6); 14 Console.WriteLine(queue.Dequeue()); 15 queue.Enqueue(7); 16 Console.WriteLine(queue.Dequeue()); 17 Console.WriteLine(queue.Dequeue()); 18 queue.Enqueue(8); 19 queue.Enqueue(9); 20 queue.Enqueue(10); 21 queue.Enqueue(11); 22 } 23 catch (ArgumentOutOfRangeException e) 24 { 25 Console.WriteLine(nameof(ArgumentOutOfRangeException) + e.Message); 26 } 27 catch (NullReferenceException e) 28 { 29 Console.WriteLine(nameof(NullReferenceException) + e.Message); 30 }