双端队列实际上就是一个双向链表,只不过他只允许将队头或队尾元素出队。双端队列有一个很有意思的特点,因为他本质是双向链表,所以他内部每一个结点都要存放其上一个节点和下一个节点的指针,而按照之前的实现使用链表实现栈()和队列()中可以发现他同时具备了栈和队列的实现特点,再栈中每一个元素都是只存储了其上一个元素的位置,而队列是只存储了下一个元素的位置,而双端队列却存储了前后元素的位置,由此它同时具有栈和队列的功能。
在双端队列中,如果你只在一头做插入和移除操作,那么它实际就是一个栈。如果你在一天做插入操作,另一条做移除操作,那么它实际就是一个队列。
实现方式其实就是和实现双向链表是一样的,只不过他只提供取头节点或尾节点的接口。在C#的.net5之后自带了双向链表(LinkedList)。以下是我的实现:
public class Dequeue<T>
{
private LinkedNode<T> first;
private LinkedNode<T> last;
private int count;
public int Count => count;
public void AddFirst(T value)
{
LinkedNode<T> node = new LinkedNode<T>(value);
if (first == null)
{
first = node;
last = node;
}
else
{
first.Previous = node;
node.Next = first;
first = node;
}
count++;
}
public void AddLast(T value)
{
LinkedNode<T> node = new LinkedNode<T>(value);
if (last == null)
{
first = node;
last = node;
}
else
{
last.Next = node;
node.Previous = last;
last = node;
}
count++;
}
public T RemoveFirst()
{
if (count == 0)
new Exception("Dequeue is empty!");
T value = first.Value;
first = first.Next;
if (first != null)
first.Previous = null;
count--;
return value;
}
public T RemoveLast()
{
if (count == 0)
new Exception("Dequeue is empty!");
T value = last.Value;
last = last.Previous;
if (last != null)
last.Next = null;
count--;
return value;
}
}
public class LinkedNode<T>
{
public T Value { get; set; }
public LinkedNode<T> Previous { get; set; }
public LinkedNode<T> Next { get; set; }
public LinkedNode(T value)
{
Value = value;
}
}
实现上的思路实际上就是使用一个两个指针的节点,一个指向其前节点,一个指向其后节点。然后维护一个前节点和一个后节点。根据操作的方式去选择改变前节点还是后节点。
因篇幅问题不能全部显示,请点此查看更多更全内容