队列
队列(Queue)是插入操作限定在表的尾部而其他操作限定在表头的线性表。
队列操作按照先进先出,后进后出的原则进行。主要操作包括在队尾插入元素、在队头删除元素、取队头元素和判空等。
BCL中的队列
C#2.0以下版本提供了非泛型的Queue类
C#2.0以上提供了泛型Queue类
常用方法:
- Enqueue() 入队,放在队尾
- Dequeue() 出队,移除队首元素,并返回被移除的元素
- Peek() 获取队首元素,不删除
- Clear() 清空元素
- Count() 获取队列中元素的个数
队列接口定义
public interface IQueue<T>
{
int Count { get; }
int GetLength();
bool IsEmpty();
void Clear();
void Enqueue(T item);
T Dequeue();
T Peek();
}
顺序队列
用一片连续的存储空间来存储队列中的数据元素,这样的队列称为顺序队列(Sequence Queue)。类似于顺序栈,用一维数组来存放顺序队列中的数据元素。队头位置设在数组下标为0的一端,用front表示。队尾设置在另一端,用rear表示。当队列为空时,front=rear=-1。
顺序队列实现
public class SeqQueue<T>:IQueue<T>
{
private T[] data;
private int count;//当前有多少个元素
private int front;//队首,队首元素索引-1
private int rear;//队尾,队尾元素索引
public SeqQueue(int size)
{
data = new T[size];
count = 0;
front = -1;
rear = -1;
}
public SeqQueue() : this(10)
{
}
public int Count
{
get { return count; }
}
public int GetLength()
{
return count;
}
public bool IsEmpty()
{
return count == 0;
}
public void Clear()
{
count = 0;
front = rear = -1;
}
public void Enqueue(T item)
{
if (count == data.Length)
{
Console.WriteLine("当前队列已满!");
}
else
{
if (rear == data.Length - 1)//如果队尾是最后一个数组的索引,则将新增元素放到队列第一个位置
{
data[0] = item;
rear = 0;
count++;
}
else
{
data[rear + 1] = item;
rear++;
count++;
}
}
}
public T Dequeue()
{
if (count > 0)
{
T temp = data[front + 1];
front++;
count--;
return temp;
}
else
{
Console.WriteLine("队列为空,无法取得队首数据");
return default(T);
}
}
public T Peek()
{
T temp = data[front + 1];
return temp;
}
}
链队列
队列的另外一种存储方式是链式存储,这样的队列称为链队列(Linked Queue)。同链栈一样,链队列通常用单链表来表示,它的实现是单链表的简化。由于链队列的操作只在一端进行,为了操作方便,把队头设在链表的头部,且不需要头结点。
链队列结点定义
public class Node<T>
{
private T data;
private Node<T> next;
public Node(T data)
{
this.data = data;
}
public T Data
{
get
{
return data;
}
set
{
data = value;
}
}
public Node<T> Next
{
get { return next; }
set { next = value; }
}
}
链队列实现
public class LinkedQueue<T>:IQueue<T>
{
private Node<T> front;//头节点
private Node<T> rear;//尾节点
private int count;//元素个数
public LinkedQueue()
{
front = null;
rear = null;
count = 0;
}
public int Count
{
get { return count; }
}
public int GetLength()
{
return count;
}
public bool IsEmpty()
{
return count == 0;
}
public void Clear()
{
front = null;
rear = null;
count = 0;
}
public void Enqueue(T item)
{
Node<T> newNode = new Node<T>(item);
if (count == 0)
{
front = newNode;
rear = newNode;
count = 1;
}
else
{
rear.Next = newNode;
rear = newNode;
count++;
}
}
public T Dequeue()
{
if (count == 0)
{
Console.WriteLine("队列为空,无法出队");
return default(T);
}else if(count == 1)
{
T temp = front.Data;
front = rear = null;
count = 0;
return temp;
}
else
{
T temp = front.Data;
front = front.Next;
count--;
return temp;
}
}
public T Peek()
{
if (front != null)
{
return front.Data;
}
else
{
return default(T);
}
}
}
栈和队列的应用举例
编程判断一个字符串是否是回文。eg:"ABCDEDCBA"是回文。
算法思想:把第一个字符与最后一个字符相比较,第二个字符与倒数第二个字符比较。如果每次都相等,则为回文,反之则不是回文。因此,可以把字符序列分别入队列和栈,然后出个出队和出栈,并比较出队的字符与出栈的字符是否相等,若全部相等,则为回文。
string str = Console.ReadLine();
Stack<char> stack = new Stack<char>();
Queue<char> queue = new Queue<char>();
for (int i = 0; i < str.Length; i++)
{
stack.Push(str[i]);
queue.Enqueue(str[i]);
}
bool isHui = true;
while (stack.Count > 0)
{
if (stack.Pop() != queue.Dequeue())
{
isHui = false;
break;
}
}
Console.WriteLine("是否是回文字符串:" + isHui);
Console.ReadKey();