Alternative to stack

I work in a .NET environment using C #. I need an alternative for the Stack data structure. Some kind of bound stack. The number of elements in the collection should not exceed some fixed given number. And, if this number is reached and the new element is pressed, then most of the old elements must be deleted. I need this to store commands for Undo / Redo strategies.

+7
source share
5 answers
+5
source

A circular buffer should do the job; It's easy enough to wrap a list or array, but nothing is built in AFAIK.

+7
source

.Net is quite insufficient for collection types. Here you will find the collection library here . Use CircularQueue .

+2
source

This is a limited capacity stack implementation. Having reached the specified capacity, the lower elements of the stack exceed the capacity. You can iterate over the contained objects and set the index to a position (for example, rewind) to drop several records at the same time when a new item is pushed onto the stack.

This is its own implementation with some goodies, which prevents you from processing more than one list if you need to go back in history and forward again (built-in).

public class DiscardingStack<TObject> : IEnumerable<TObject> { private readonly int capacity; private readonly List<TObject> items; private int index = -1; public DiscardingStack(int capacity) { this.capacity = capacity; items = new List<TObject>(capacity); } public DiscardingStack(int capacity, IEnumerable<TObject> collection) : this(capacity) { foreach (var o in collection) { Push(o); } } public DiscardingStack(ICollection<TObject> collection) : this(collection.Count, collection) { } public void Clear() { if (items.Count >= 0) { items.Clear(); index = items.Count - 1; } } public int Index { get { return index; } set { if (index >= 0 && index < items.Count) { index = value; } else throw new InvalidOperationException(); } } public int Count { get { return items.Count; } } public TObject Current { get { return items[index]; } set { index = items.IndexOf(value); } } public int Capacity { get { return capacity; } } public TObject Pop() { if (items.Count <= 0) throw new InvalidOperationException(); var i = items.Count - 1; var removed = items[i]; items.RemoveAt(i); if (index > i) index = i; return removed; } public void Push(TObject item) { if (index == capacity - 1) { items.RemoveAt(0); index--; } else if (index < items.Count - 1) { var removeAt = index + 1; var removeCount = items.Count - removeAt; items.RemoveRange(removeAt, removeCount); } items.Add(item); index = items.Count - 1; } public TObject Peek() { return items[items.Count-1]; } public TObject this[int i] { get { return items[i]; } } public IEnumerator<TObject> GetEnumerator() { return items.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } 

In any case, creating a stack that discards items when it reaches maximum capacity should be implemented using LinkedList (as suggested above) if your list is huge (avoids copying). Thus, the idea of ​​LinkedList might be better in this case instead of wrapping the list if the maximum buffer is a high value.

I also recommend packing Push (), Pop (), etc. to the interface (e.g. IStack). Unfortunately, there is no IStack interface predefined in .Net (afaik).

+2
source

There is no built-in class for this in the Framework. (we are not going to automatically delete the data). But you can very well Extend the Stack class and override Push / Pop and other methods to suit your needs.

+1
source

All Articles