题外话:西巴,感觉身体好沉,好累。。。但还是要学的!!!
给大家推荐一个Up樱花兔,一个很厉害的妹子,看看她的视频,我没脸不努力。
PS: 本文的重点是代码代码代码!而不是数据结构的一些基础概念和分类;
完全没接触过的同学,可以去看B站王卓教授的视频。
1.什么是栈?
- 只能从表尾插入/删除的线性表,即先进后出;
- 和手枪弹匣一样,先入匣的子弹,最后才能被射出。
2.怎么更好的理解栈?
- 你可以认为,栈就是一个普通的线性表,只是这个线性表有一个特性:必须在表尾新增/删除元素。
- 看,这么理解是不是方便多了?
- 再极端点,你可以理解为:他就是一个数组,但你不能动除了最后一个元素以外的其他元素。
3.栈有几种?
- 顺序栈:用顺序表(数组)实现的栈;
- 链栈:用链表实现的栈。
4.图解顺序栈
5.图解链栈
6.代码实现顺序栈
namespace YoyoCode
{
/// <summary>
/// 顺序栈
/// </summary>
/// <typeparam name="T"></typeparam>
internal class SqStack<T>
{
private T[] _array;
//栈中元素个数
private int _count = 0;
private const int _defaultSize = 4;
public SqStack(int size)
{
_array = new T[size];
}
public SqStack()
{
_array = new T[_defaultSize];
}
public int Count {
get {
return _count; } }
/// <summary>
/// 栈是否为空
/// </summary>
/// <returns>bool,是否为空</returns>
public bool IsEmpty()
{
return _count == 0;
}
/// <summary>
/// 清空栈
/// </summary>
public void Clear()
{
Array.Clear(_array, 0, _count);
_count = 0;
}
/// <summary>
/// 元素入栈
/// </summary>
/// <param name="value"></param>
public void Push(T value)
{
//数组扩容
if (_count == _array.Length)
{
T[] newArray = new T[2 * _array.Length];
Array.Copy(_array, newArray, _count);
_array= newArray;
}
_array[_count++] = value;
}
/// <summary>
/// 元素出栈
/// </summary>
/// <returns></returns>
public T Pop()
{
if (_count == 0) {
throw (new IndexOutOfRangeException());
}
else
{
return _array[--_count];
}
}
}
}
7.代码实现链栈
namespace DataStruct
{
internal class LinkedStack<T>
{
public LinkedStackNode<T> Top;
//栈中元素个数
private int _count = 0;
public int Count {
get {
return _count; } }
/// <summary>
/// 栈是否为空
/// </summary>
/// <returns>bool,是否为空</returns>
public bool IsEmpty()
{
return _count == 0;
}
/// <summary>
/// 清空栈
/// </summary>
public void Clear()
{
Top = null;
_count = 0;
}
/// <summary>
/// 元素入栈
/// </summary>
/// <param name="value"></param>
public void Push(T value)
{
LinkedStackNode<T> node = new LinkedStackNode<T>(value);
if (IsEmpty())
{
Top = node;
}
else
{
node.Next = Top;
Top = node;
}
_count++;
}
/// <summary>
/// 元素出栈
/// </summary>
/// <returns></returns>
public T Pop()
{
if (_count == 0)
{
throw (new NullReferenceException());
}
else
{
var res = Top.Data;
Top = Top.Next;
_count--;
return res;
}
}
}
internal class LinkedStackNode<T>
{
public T Data;
public LinkedStackNode<T> Next;
public LinkedStackNode(T data)
{
Data = data;
}
}
}
8.选用顺序栈还是链栈?
- 两者本质上区别不大,因为不会涉及到表头/中元素的插入和删除,只是在表尾操作的话,时间复杂度都是O(1);
- 但是顺序栈可能在Push时发生数组扩容,同比链栈会消耗更多的时间。
- 顺序栈比较常用,包括C#Stack<>的底层也是顺序栈。
结束语: 半夜11点出去遛猫,回来之后心情舒畅。果然,人也得出去走走才行呀~