RoundStack:限制容量的堆栈类
最近在实现操作历史的功能,发现了一个可以设定容量的Stack类,在某些场合非常有用。这个类叫RoundStack,数据结构设计上很有意思,值得借鉴,所以推荐给大家。
RoundStack
using System;
using System.Collections.Generic;
using System.Text;
namespace GenericUndoRedo
{
/// <summary>
/// Stack with capacity, bottom items beyond the capacity are discarded.
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public class RoundStack<T>
{
private T[] items; // items.Length is Capacity + 1
// top == bottom ==> full
private int top = 1;
private int bottom = 0;
/// <summary>
/// Gets if the <see cref="RoundStack<T>"/> is full.
/// </summary>
public bool IsFull
{
get
{
return top == bottom;
}
}
/// <summary>
/// Gets the number of elements contained in the <see cref="RoundStack<T>"/>.
/// </summary>
public int Count
{
get
{
int count = top - bottom - 1;
if (count < 0)
count += items.Length;
return count;
}
}
/// <summary>
/// Gets the capacity of the <see cref="RoundStack<T>"/>.
/// </summary>
public int Capacity
{
get
{
return items.Length - 1;
}
}
/// <summary>
/// Creates <see cref="RoundStack<T>"/> with given capacity
/// </summary>
/// <param name="capacity"></param>
public RoundStack(int capacity)
{
if (capacity < 1)
throw new ArgumentOutOfRangeException("Capacity need to be at least 1");
items = new T[capacity + 1];
}
/// <summary>
/// Removes and returns the object at the top of the <see cref="RoundStack<T>"/>.
/// </summary>
/// <returns></returns>
public T Pop()
{
if (Count > 0)
{
T removed = items[top];
items[top--] = default(T);
if (top < 0)
top += items.Length;
return removed;
}
else
throw new InvalidOperationException("Cannot pop from emtpy stack");
}
/// <summary>
/// Inserts an object at the top of the <see cref="RoundStack<T>"/>.
/// </summary>
/// <param name="item"></param>
public void Push(T item)
{
if (IsFull)
{
bottom++;
if (bottom >= items.Length)
bottom -= items.Length;
}
if (++top >= items.Length)
top -= items.Length;
items[top] = item;
}
/// <summary>
/// Returns the object at the top of the <see cref="RoundStack<T>"/> without removing it.
/// </summary>
public T Peek()
{
return items[top];
}
/// <summary>
/// Removes all the objects from the <see cref="RoundStack<T>"/>.
/// </summary>
public void Clear()
{
if (Count > 0)
{
for (int i = 0; i < items.Length; i++)
{
items[i] = default(T);
}
top = 1;
bottom = 0;
}
}
}
}
using System.Collections.Generic;
using System.Text;
namespace GenericUndoRedo
{
/// <summary>
/// Stack with capacity, bottom items beyond the capacity are discarded.
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public class RoundStack<T>
{
private T[] items; // items.Length is Capacity + 1
// top == bottom ==> full
private int top = 1;
private int bottom = 0;
/// <summary>
/// Gets if the <see cref="RoundStack<T>"/> is full.
/// </summary>
public bool IsFull
{
get
{
return top == bottom;
}
}
/// <summary>
/// Gets the number of elements contained in the <see cref="RoundStack<T>"/>.
/// </summary>
public int Count
{
get
{
int count = top - bottom - 1;
if (count < 0)
count += items.Length;
return count;
}
}
/// <summary>
/// Gets the capacity of the <see cref="RoundStack<T>"/>.
/// </summary>
public int Capacity
{
get
{
return items.Length - 1;
}
}
/// <summary>
/// Creates <see cref="RoundStack<T>"/> with given capacity
/// </summary>
/// <param name="capacity"></param>
public RoundStack(int capacity)
{
if (capacity < 1)
throw new ArgumentOutOfRangeException("Capacity need to be at least 1");
items = new T[capacity + 1];
}
/// <summary>
/// Removes and returns the object at the top of the <see cref="RoundStack<T>"/>.
/// </summary>
/// <returns></returns>
public T Pop()
{
if (Count > 0)
{
T removed = items[top];
items[top--] = default(T);
if (top < 0)
top += items.Length;
return removed;
}
else
throw new InvalidOperationException("Cannot pop from emtpy stack");
}
/// <summary>
/// Inserts an object at the top of the <see cref="RoundStack<T>"/>.
/// </summary>
/// <param name="item"></param>
public void Push(T item)
{
if (IsFull)
{
bottom++;
if (bottom >= items.Length)
bottom -= items.Length;
}
if (++top >= items.Length)
top -= items.Length;
items[top] = item;
}
/// <summary>
/// Returns the object at the top of the <see cref="RoundStack<T>"/> without removing it.
/// </summary>
public T Peek()
{
return items[top];
}
/// <summary>
/// Removes all the objects from the <see cref="RoundStack<T>"/>.
/// </summary>
public void Clear()
{
if (Count > 0)
{
for (int i = 0; i < items.Length; i++)
{
items[i] = default(T);
}
top = 1;
bottom = 0;
}
}
}
}
代码出处:Generic Memento Pattern for Undo-Redo in C#
作者:黎波
博客:http://bobli.cnblogs.com/
日期:2011年1月7日