数据结构-队列
队列也是一种操作受限的数据结构(先进先出)。
队列用数组实现称为顺序队列,队列用链表实现称为链式队列。
顺序队列
// 顺序队列 数组实现
public class ArrayQueue
{
private string[] arrauqueue;
private int n;
private int head = 0; // 队头
private int tail = 0; // 队尾
public ArrayQueue(int N)
{
arrauqueue = new string[N];
n = N;
tail = 0;
head = 0;
}
// 入队操作 队尾 tail
public bool enqueue(string item)
{
if(tail == n) return false;
arrauqueue[tail] = item;
tail++;
return true;
}
// 出队操作 队头 head
public string dequeue()
{
if (head == n) return null;
var item = arrauqueue[head];
head++;
return item;
}
static void Main(string[] args)
{
var arrayqueue = new ArrayQueue(3);
arrayqueue.enqueue("one");
arrayqueue.enqueue("two");
Console.WriteLine(arrayqueue.dequeue());
Console.WriteLine(arrayqueue.dequeue());
Console.ReadKey();
}
顺序队列-数据搬移
此时会出现一个问题,如下图所示情况,此时队列不为空,但是当元素j请求入队时请求失败。
下面所列代码初始化大小为3的数组,在three请求入队前进行了两次出队操作,在four请求入队时出错。
static void Main(string[] args)
{
var arrayqueue = new ArrayQueue(3);
arrayqueue.enqueue("one");
arrayqueue.enqueue("two");
Console.WriteLine(arrayqueue.dequeue());
Console.WriteLine(arrayqueue.dequeue());
if (arrayqueue.enqueue("three"))
{
Console.WriteLine("enqueue three success");
}
else
{
Console.WriteLine("enqueue three error");
}
if (arrayqueue.enqueue("four"))
{
Console.WriteLine("enqueue four success");
}
else
{
Console.WriteLine("enqueue four error");
}
Console.ReadKey();
}
此时可以在入队操作时检查队尾是否到达数组下标上限,达到上限时进行数据搬移操作。
public bool enqueue(string item)
{
if(tail == n)
{
if (head == 0) return false;// 队列满
for(int i = head; i < tail; i++)
{
arrauqueue[i - head] = arrauqueue[i];
}
tail = tail - head; // 数据搬移后需要更新队头指针和队尾指针
head = 0;
}
arrauqueue[tail] = item;
tail++;
return true;
}
顺序队列-循环队列
循环队列不需要进行数据搬移工作。
- 队空 head == tail
- 队满 (tail+1) % n = head
通过队空和队满的条件可知,循环队列会浪费数组中的一个的存储空间。
// 循环队列
public class CircularQueue
{
private string[] circularqueue;
private int n;
private int head;
private int tail;
public CircularQueue(int N)
{
circularqueue = new string[N];
n = N;
head = 0;
tail = 0;
}
// 入队操作
public bool enqueue(string item)
{
if ((tail + 1) % n == head) return false;// 队满
circularqueue[tail] = item;
tail = (tail + 1) % n;
return true;
}
// 出队操作
public string dequeue()
{
if (head == tail) return null;// 队空
var res = circularqueue[head];
head = (head + 1) % n;
return res;
}
}
static void Main(string[] args)
{
var circularqueue = new CircularQueue(3);
circularqueue.enqueue("one");
circularqueue.enqueue("two");
Console.WriteLine(circularqueue.dequeue());
circularqueue.enqueue("three");
Console.WriteLine(circularqueue.dequeue());
circularqueue.enqueue("four");
Console.WriteLine(circularqueue.dequeue());
Console.ReadKey();
}
链式队列
// 链式队列 链表实现
public class LinkedQueue
{
class Node
{
public string Value { get; set; }
public Node Next { get; set; }
public Node(string value)
{
Value = value;
}
}
private Node head; // 队头
private Node tail; // 队尾
// 入队操作
public void enqueue(string item)
{
Node newnode = new Node(item);
if (head == null)
{
head = newnode;
tail = newnode;
}
else
{
tail.Next = newnode;
tail = newnode;
}
}
// 出队操作
public string dequeue()
{
if(head == null)
{
return "queue is empty";
}
else
{
var item = head.Value;
head = head.Next;
return item;
}
}
}
static void Main(string[] args)
{
var linkedqueue = new LinkedQueue();
linkedqueue.enqueue("three");
linkedqueue.enqueue("four");
Console.WriteLine(linkedqueue.dequeue());
Console.WriteLine(linkedqueue.dequeue());
Console.ReadKey();
}