栈的定义不需要多说,相信大家都非常熟悉,但是,在实际应用中栈的应用我们很少想到会去用栈结构,先上代码看下用法:
Stack st = new Stack();
st.Push('A');
st.Push('B');
st.Push('C');
st.Push('D');
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
st.Push('E');
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
st.Pop();
st.Pop();
st.Pop();
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.ReadLine();
现在我们自己实现一个栈结构:
/// <summary>
/// 栈
/// </summary>
public class MyStack
{
/// <summary>
/// 栈的实现还是使用数组的方式存储
/// </summary>
public Object[] content {
get; set; }
/// <summary>
/// 栈深度
/// </summary>
public int size {
get; set; }
/// <summary>
/// 默认开始深度
/// </summary>
public int defaultSize {
get; set; } = 10;
/// <summary>
/// 初始化 默认深度
/// </summary>
public MyStack()
{
content = new object[defaultSize];
size = 0;
}
/// <summary>
/// 压栈
/// </summary>
/// <param name="obj"></param>
public virtual void Push(Object obj)
{
//如果数组满了,则扩容(翻倍扩容)
if (size == content.Length)
{
//扩容次数为2的指数级
Object[] newArray = new Object[2 * content.Length];
//将原内容拷贝到新的数组中 (扩容次数 2的指数级扩容,减少拷贝带来的时间消耗)
Array.Copy(content,0,newArray,0,size);
content = newArray;
}
//写入数组
content[size++] = obj;
}
/// <summary>
/// 取下一个出栈值,但不删除 (偷看下~)
/// </summary>
/// <returns></returns>
public virtual Object Peek()
{
if (size == 0)
throw new InvalidOperationException("空栈");
return content[size - 1];
}
/// <summary>
/// 出栈
/// </summary>
/// <returns></returns>
public virtual Object Pop()
{
if (size == 0)
throw new InvalidOperationException("空栈");
Object obj = content[--size];
content[size] = null;
return obj;
}
//实现该方法是为了 暂不实现 ICollection -
public void ShowAll()
{
for (int i=size-1;i>=0;i--)
{
Console.Write($" {content[i]}");
}
Console.WriteLine();
}
}
/// <summary>
/// 异步栈
/// </summary>
public class MySyncStack : MyStack
{
private MyStack myStack;
private Object lookObj;
public override void Push(Object value)
{
lock (lookObj)
{
myStack.Push(value);
}
}
public override Object Pop()
{
lock (lookObj)
{
return myStack.Pop();
}
}
public override Object Peek()
{
lock (lookObj)
{
return myStack.Peek();
}
}
}
可以看出,其实栈还是用数组结构来实现的,异步栈在栈的基础上增加了锁。
测试下:
MyStack st = new MyStack();
st.Push('A');
st.Push('B');
st.Push('C');
st.Push('D');
st.ShowAll();
st.Push('E');
st.ShowAll();
st.Pop();
st.Pop();
st.Pop();
st.ShowAll();
Console.ReadLine();