By提供的解决方案Greg Dean => dropout stack
非常好,但我认为主要问题是关于在堆栈溢出时移除堆栈底部但是提供的解决方案只是在堆栈被填满后替换堆栈的最后一项,所以你不会得到真实的历史,
但是要获得真实的历史记录,一旦列表达到您的特定容量,您需要移动列表,但这是一个扩展操作,
所以我认为最好的解决方案是链表
这是我解决问题的方法
public class HistoryStack<T>
{
private LinkedList<T> items = new LinkedList<T>();
public List<T> Items => items.ToList();
public int Capacity { get;}
public HistoryStack(int capacity)
{
Capacity = capacity;
}
public void Push(T item)
{
// full
if (items.Count == Capacity)
{
// we should remove first, because some times, if we exceeded the size of the internal array
// the system will allocate new array.
items.RemoveFirst();
items.AddLast(item);
}
else
{
items.AddLast(new LinkedListNode<T>(item));
}
}
public T Pop()
{
if (items.Count == 0)
{
return default;
}
var ls = items.Last;
items.RemoveLast();
return ls == null ? default : ls.Value;
}
}
测试一下
var hs = new HistoryStack<int>(5);
hs.Push(1);
hs.Push(2);
hs.Push(3);
hs.Push(4);
hs.Push(5);
hs.Push(6);
hs.Push(7);
hs.Push(8);
var ls = hs.Items;
Console.WriteLine(String.Join(",", ls));
Console.WriteLine(hs.Pop());
Console.WriteLine(hs.Pop());
hs.Push(9);
Console.WriteLine(hs.Pop());
Console.WriteLine(hs.Pop());
Console.WriteLine(hs.Pop());
Console.WriteLine(hs.Pop());
Console.WriteLine(hs.Pop()); // empty
Console.WriteLine(hs.Pop()); // empty
结果
4,5,6,7,8
8
7
9
6
5
4
0
0