1.首先是数组实现方式
接口代码:
internal interface IArrayStack<T>
{
/// <summary>
/// 向栈顶压入数据
/// </summary>
/// <param name="value">值</param>
void Push(T value);
/// <summary>
/// 弹出栈顶数据
/// </summary>
void Pop();
/// <summary>
/// 查看栈顶数据,但不弹出
/// </summary>
/// <returns></returns>
T Peek();
/// <summary>
/// 栈是否为空
/// </summary>
/// <returns></returns>
bool IsEmpty();
/// <summary>
/// 转数组
/// </summary>
/// <returns></returns>
T[] ToArray();
/// <summary>
/// 清除所有值
/// </summary>
void Clear();
/// <summary>
/// 是否存在元素
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
bool Contains(T item);
/// <summary>
/// 容量
/// </summary>
int Capacity { get; }
/// <summary>
/// 有效数量
/// </summary>
int Count { get; }
/// <summary>
/// 压缩容器(默认0.5)
/// </summary>
/// <param name="mul">范围[0,1]</param>
void CompressedContainer(float mul=0.5f);
}
接着看实现类:
/// <summary>
/// 栈---数组实现
/// </summary>
/// <typeparam name="T"></typeparam>
internal class ArrayStack<T> : IArrayStack<T>
{
private T[] _stack;
public int Capacity { get; private set; }
public int Count { get { return _top + 1; } private set { Count = value; } }
private int _top = -1;
private int _maxCapacity;
public ArrayStack()
{
}
public ArrayStack(int capacity)
{
if (capacity < 0)
throw new ArgumentOutOfRangeException(nameof(capacity));
_stack = new T[capacity];
Capacity = capacity;
_maxCapacity = capacity;
}
public void Clear()
{
Capacity = 0;
Count = 0;
_top = -1;
_stack = null;
}
public bool Contains(T item)
{
foreach (T item2 in _stack)
{
if (item2.Equals(item))
return true;
}
return false;
}
public bool IsEmpty()
{
return _top == -1;
}
public T Peek()
{
if (IsEmpty())
return default(T);
return _stack[0];
}
public void Pop()
{
if (IsEmpty())
return;
int count = _top;
for (int i = 0; i < count; i++)
{
(_stack[i], _stack[i + 1]) = (_stack[i + 1], _stack[i]);
}
--_top;
}
public void Push(T value)
{
int count = Count;
if (_maxCapacity==0)
{
if (count == Capacity)
{
T[] tempStack = null;
if (Capacity == 0)
{
Capacity = 4;
tempStack = new T[Capacity];
_stack = tempStack;
}
else
{
Capacity <<= 1;
if (Capacity > Array.MaxLength)
Capacity = Array.MaxLength;
tempStack = new T[Capacity];
Array.Copy(_stack, tempStack, count);
_stack = null;
_stack = tempStack;
}
tempStack = null;
}
}
else
{
if(count >= _maxCapacity)
Pop();
}
_stack[++_top] = value;
}
public T[] ToArray()
{
int count = Count;
T[] tempStack = new T[count];
Array.Copy(_stack, tempStack, count);
return tempStack;
}
public override string ToString()
{
return String.Join(',', ToArray());
}
public void CompressedContainer(float mul = 0.5f)
{
int count = Count;
// 压缩
if (Capacity-count>= count*mul)
{
T[] tempStack = new T[count];
Array.Copy(_stack, tempStack, count);
_stack = null;
_stack = tempStack;
tempStack = null;
}
}
}
2.链表实现方式
首先看接口:
/// <summary>
/// 自定义栈
/// </summary>
internal interface ILinkedStack<T>
{
/// <summary>
/// 向栈顶压入数据
/// </summary>
/// <param name="value">值</param>
void Push(T value);
/// <summary>
/// 向栈顶压入数据
/// </summary>
/// <param name="value">值</param>
void Push(SingleLinkedNode<T> value);
/// <summary>
/// 弹出栈顶数据
/// </summary>
void Pop();
/// <summary>
/// 查看栈顶数据,但不弹出
/// </summary>
/// <returns></returns>
T Peek();
/// <summary>
/// 栈是否为空
/// </summary>
/// <returns></returns>
bool IsEmpty();
/// <summary>
/// 转数组
/// </summary>
/// <returns></returns>
T[] ToArray();
/// <summary>
/// 清除所有值
/// </summary>
void Clear();
/// <summary>
/// 是否存在元素
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
bool Contains(T item);
/// <summary>
/// 有效数量
/// </summary>
int Count { get; }
}
接着看实现类:
/// <summary>
/// 链表实现栈---头插入法
/// 主要思路:
/// 头插入法:每次插入值的Next都指向之前的头地址,例如人newNode.Next = oldNode.Next;移除时每次要移动到链表尾部前一个,使其Next=null。
/// 尾插入法:与头插入法相反
/// </summary>
/// <typeparam name="T"></typeparam>
internal class LinkedStack<T> : ILinkedStack<T>
{
/// <summary>
/// 栈顶
/// </summary>
public SingleLinkedNode<T> Top { get; private set; }
/// <summary>
/// 数量
/// </summary>
public int Count { get; private set; }
public LinkedStack()
{
}
public LinkedStack(IEnumerable<T> values)
{
if (values != null)
{
int tempCount = values.Count();
Count += tempCount;
if (tempCount > 0)
{
SingleLinkedNode<T> tempTop = new SingleLinkedNode<T>(values.First());
--tempCount;
for (int i = 1; i < tempCount; i++)
{
var tempValue = new SingleLinkedNode<T>(values.ElementAt(i));
tempValue.Next = tempTop;
tempTop = tempValue;
}
if (IsEmpty())
Top = tempTop;
else
{
tempTop.Next = Top;
Top = tempTop;
}
}
}
}
public void Clear()
{
Top = null;
Count = 0;
}
public bool Contains(T item)
{
if (IsEmpty())
return false;
SingleLinkedNode<T> tempNode = Top;
while (tempNode != null)
{
if (tempNode.Data.Equals(item))
return true;
tempNode = tempNode.Next;
}
return false;
}
public bool IsEmpty()
{
return Count == 0;
}
public T Peek()
{
if (IsEmpty())
throw new Exception("栈空");
return Top.Data;
}
public void Pop()
{
if (IsEmpty())
return;
SingleLinkedNode<T> tempNode = Top;
int tempCount = Count - 2;
for (int i = 0; i < tempCount; i++)
{
tempNode = tempNode.Next;
}
tempNode.Next = null;
--Count;
}
public void Push(T value)
{
SingleLinkedNode<T> valueNode = new SingleLinkedNode<T>(value);
if (IsEmpty())
Top = valueNode;
else
{
SingleLinkedNode<T> tempNode = Top;
valueNode.Next = tempNode;
Top = valueNode;
}
++Count;
}
public void Push(SingleLinkedNode<T> value)
{
SingleLinkedNode<T> valueNode = value.DeepClone<T>();
if (IsEmpty())
Top = valueNode;
else
{
SingleLinkedNode<T> tempNode = Top;
valueNode.Next = tempNode;
Top = valueNode;
}
++Count;
}
public T[] ToArray()
{
T[] array = new T[Count];
int index = 0;
SingleLinkedNode<T> tempNode = Top;
while (tempNode != null)
{
array[index++] = tempNode.Data;
tempNode = tempNode.Next;
}
return array;
}
public override string ToString()
{
return Top.ToString();
}
}
注:链表节点
[Serializable]
public class SingleLinkedNode<T> : ICloneable
{
public T Data { get; set; }
public SingleLinkedNode<T> Next { get; set; }
public SingleLinkedNode()
{
Data = default(T);
Next = null;
}
public SingleLinkedNode(T data)
{
Data = data;
Next = null;
}
public SingleLinkedNode(T data, SingleLinkedNode<T> node)
{
Data = data;
Next = node;
}
/// <summary>
/// 浅克隆
/// </summary>
/// <returns></returns>
public object Clone()
{
return this.MemberwiseClone();
}
/// <summary>
/// 深克隆
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public SingleLinkedNode<T> DeepClone<T>()
{
object obj = null;
// 将对象序列化成内存中的二进制流
BinaryFormatter binaryFormatter = new BinaryFormatter();
using MemoryStream memoryStream = new MemoryStream();
binaryFormatter.Serialize(memoryStream, this);
// 将二进制流反序列成对象
using MemoryStream memoryStream2 = new MemoryStream(memoryStream.ToArray());
BinaryFormatter binaryFormatter2 = new BinaryFormatter();
obj = binaryFormatter2.Deserialize(memoryStream2);
return (SingleLinkedNode<T>)obj;
}
public override bool Equals(object? obj)
{
// 判断是否为引用相等
if (ReferenceEquals(this, obj))
return true;
if (obj == null || this == null)
return false;
SingleLinkedNode<T> tempNode = obj as SingleLinkedNode<T>;
if (tempNode == null)
return false;
return this.GetHashCode() == tempNode.GetHashCode();
}
public override int GetHashCode()
{
return (this.Data, this.Next).GetHashCode();
}
public static bool operator == (SingleLinkedNode<T> first, SingleLinkedNode<T> second)
{
// 判断是否为引用相等
if (ReferenceEquals(first, second))
return true;
return first.Equals(second);
}
public static bool operator !=(SingleLinkedNode<T> first, SingleLinkedNode<T> second)
{
// 判断是否为引用相等
if (ReferenceEquals(first, second))
return false;
return !first.Equals(second);
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine(this.Data?.ToString());
SingleLinkedNode<T> tempNode = this.Next;
while (tempNode != null)
{
stringBuilder.AppendLine(tempNode.Data.ToString());
tempNode = tempNode.Next;
}
string ads=stringBuilder.ToString();
return stringBuilder.ToString();
}
}