这标题是不是太长了,这次介绍的数据结构是栈,栈和队列还有线性表这三种数据结构的数据元素以及他们数据元素之间的逻辑关系是完全相同的,都是一对一的线性关系,区别在于,线性表的操作不受限制,而栈和队列的操作收到限制。
这里先说栈:栈的操作只能在表尾一端进行,表尾为称为栈顶(Top),而另一端是固定的称为栈顶(Bottom)。当栈里没有元素的时候叫做是空栈,栈是线性表的一种形式,也是通过数组来实现的,我们把只能在表的尾端进行操作的线性表叫做栈。
因为栈只有一端可以操作,所以栈有在处理数据时有两个特点:后进先出(Last In First Out)和先进后出(First In Last Out)。并且C#也提供了泛型的Stack类,这是封装好的栈。
并且栈也有两种顺序栈和链栈,顺序栈和顺序表类似,今天要实现的是顺序栈
接下来就自己来定义并实现一个顺序栈
第一步、定义接口
这里只写了一些重要方法的接口,
/// <summary>
/// 栈的接口 栈的实现方式也分两种,顺序栈和链栈
/// </summary>
/// <typeparam name="T"></typeparam>
interface IStackDs<T>
{
int Count { get; }
int GetLength();
bool IsEnpty();
void Clear();
void Push(T item);//入栈(写入/增加元素)
T Pop();//出栈(删除数据)
T Peek();//取栈顶元素
}
第二部、用顺序栈的方式实现接口
顺序栈和顺序表处理储存数据的方式不同以外,还有一点不同,顺序表里面的count是用来表长的,但是顺序栈里面的top,虽然也会随数据的增减而增减,但是top是一直指向栈顶的元素,他被称为指针。
因为和顺序表一样是使用数组来存储数据,所以我写了一个返回,储存数组的原始数据的数组,这样可以更清楚的理解顺序栈的原理
/// <summary>
/// 栈的实现————顺序栈
/// </summary>
class SeqStack<T> : IStackDs<T>
{
private T[] data;//顺序栈和顺序表一样都是用数组存储数据
private int top;//指针,永远指向栈顶
public SeqStack(int size)
{
data = new T[size];
top = -1;//空栈时,指针指向-1
}
public SeqStack():this(10)
{
}
/// <summary>
/// 数据个数属性
/// </summary>
public int Count
{
get { return top + 1; }
}
/// <summary>
/// 清空栈
/// </summary>
public void Clear()
{
top = -1;
}
/// <summary>
/// 返回长度
/// </summary>
/// <returns></returns>
public int GetLength()
{
return Count;
}
/// <summary>
/// 是否为空
/// </summary>
/// <returns></returns>
public bool IsEnpty()
{
return Count == 0;
}
/// <summary>
/// 返回栈顶数据
/// </summary>
/// <returns></returns>
public T Peek()
{
return data[top];
}
/// <summary>
/// 出栈,删除栈顶数据
/// </summary>
/// <returns></returns>
public T Pop()
{
T temp = data[top];
top--;
return temp;
}
/// <summary>
/// 入栈,增加数据
/// </summary>
/// <param name="item"></param>
public void Push(T item)
{
if (Count == data.Length)//数组满了
{
T[] temp = new T[Count*2];
for (int i = 0; i < data.Length; i++)
{
temp[i] = data[i];
}
data = temp;
}
top++;
data[top] = item;
}
public T[] GetZero
{
get { return data; }
}
}
第三部、测试顺序栈
class Program
{
static void Main(string[] args)
{
//栈测试————顺序栈
SeqStack<int> myStack = new SeqStack<int>();
//写入
Console.WriteLine("写入");
for (int i = 0; i < 100; i++)
{
myStack.Push(i);
}
Console.WriteLine("长度" + myStack.Count);
Console.WriteLine("长度" + myStack.GetLength());
Console.WriteLine("是否为空" + myStack.IsEnpty());
//清空顺序栈
Console.WriteLine("清空顺序栈");
myStack.Clear();
Console.WriteLine();
Console.WriteLine("长度" + myStack.Count);
Console.WriteLine("长度" + myStack.GetLength());
Console.WriteLine("是否为空" + myStack.IsEnpty());
//打印储存数据数组的元素
Console.WriteLine("打印储存数据数组的元素");
for (int i = 0; i < myStack.GetZero.Length; i++)
{
Console.Write(myStack.GetZero[i]);
}
Console.WriteLine();
//打印储存数据数组的容量
Console.WriteLine("打印储存数据数组的容量 " + myStack.GetZero.Length);
Console.ReadKey();
}
}
测试结果截图

大家可以发现和顺序表一样,原始数组的数据其实是没有被清除,但是对于顺序栈来说他们已经清除了,添加数据的时候其实就是数据的覆盖,这一点和链表不一样,链表的数据删除就会被回收,添加数据其实是新建的。当然你也可以多写一个释放栈空间的方法,可以清除原始数组的数据,我这里没有写。这些点大家自身分别实现一下线性表中的链表和顺序表就清楚了。
分享让知识变得有意义!后续会继续更新一些学习中问题。
OJMars
InTheMars
这篇博客介绍了数据结构中的栈,强调了栈、队列和线性表的逻辑关系,并重点讲解了栈的特性——后进先出(LIFO)。文章详细展示了如何在Unity中使用C#定义和实现顺序栈,包括定义接口、实现接口和测试顺序栈的过程。


被折叠的 条评论
为什么被折叠?



