栈是一种运算受限的线性表,只允许在一端进行插入和删除操作[1](https://baike.baidu.com/item/%E6%A0%88/12808149)。这一端被称为栈顶,另一端被称为栈底[1](https://baike.baidu.com/item/%E6%A0%88/12808149)[2](https://blog.csdn.net/m0_37961948/article/details/80245008)。栈的特点是先进后出,类似于堆盘子[2](https://blog.csdn.net/m0_37961948/article/details/80245008)。栈可以用数组或链表实现
顺序栈
自定义接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02_StackTest
{
interface IStackDS<T>
{
int Count { get; }
int GetLength();
bool IsEmpty();
void Clear();
void Push(T item);
T Pop();
T Peek();
}
}
顺序栈类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02_StackTest
{
class SeqStack<T> : IStackDS<T>
{
//栈的数组结构
private T[] data;
//顶部索引
private int top;
public SeqStack(int size)
{
data = new T[size];
top = -1;
}
//给一个默认大小
public SeqStack():this(10)
{
}
public int Count
{
get
{
return top +1;
}
}
public void Clear()
{
top = -1;
}
public int GetLength()
{
return Count;
}
public bool IsEmpty()
{
return Count == 0;
}
public T Peek()
{
return data[top];
}
public T Pop()
{
T temp = data[top];
top--;
return temp;
}
public void Push(T item)
{
data[top + 1] = item;
top++;
}
}
}
链栈
根据网上的搜索结果[1](http://data.biancheng.net/view/171.html)[2](https://blog.csdn.net/qq_41727218/article/details/81210027)[3](https://blog.csdn.net/m0_61395860/article/details/122814802),链栈是栈的一种实现方法,特指用链表实现栈存储结构。链栈的实现思路和顺序栈类似,顺序栈是将数组的一端做栈底,另一端做栈顶;链栈也是如此,我们通常将链表的头部做栈顶,尾部做栈底。
有元素入栈时,只需要将其插入到链表的头部;有元素出栈时,只需要从链表的头部依次摘取结点。因此,链栈实际上是一个采用头插法插入或删除数据的链表。
定义Node
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02_StackTest
{
/// <summary>
/// 链栈的节点
/// </summary>
/// <typeparam name="T"></typeparam>
class Node<T>
{
//数据
private T data;
//节点,用于指向下一个节点
private Node<T> next;
public Node()
{
data = default(T);
next = null;
}
public Node(T data )
{
this.data = data;
next = null;
}
public Node(T data,Node<T>next)
{
this.data = data;
this.next = next;
}
public Node(Node<T> next)
{
this.next = next;
data = default(T);
}
public T Data { get { return data; } set { data =value; } }
public Node<T> Next { get { return next; } set { next = value; } }
}
}
LinkStack(栈类)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02_StackTest
{
class LinkStack<T> : IStackDS<T>
{
//栈顶元素节点
private Node<T> top;
//进入栈,都是遍历,用count=0,表示栈中元素个数
private int count = 0;
/// <summary>
/// 取得栈中元素个数
/// </summary>
public int Count => count;
/// <summary>
/// 清空栈中所有数据
/// </summary>
public void Clear()
{
count = 0;
top = null;
}
/// <summary>
/// 取得栈中元素个数
/// </summary>
/// <returns></returns>
public int GetLength()
{
return count;
}
/// <summary>
/// 判断栈中是否数据
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
return count == 0;
}
/// <summary>
/// 取得栈顶中的数据,不删除栈顶
/// </summary>
/// <returns></returns>
public T Peek()
{
return top.Data;
}
/// <summary>
/// 出栈 取得栈顶元素,然后删除
/// </summary>
/// <returns></returns>
public T Pop()
{
//获得栈顶元素
T data = top.Data;
//把top指向下一个节点
top = top.Next;
count--;
return data;
}
/// <summary>
/// 入栈
/// </summary>
/// <param name="item"></param>
public void Push(T item)
{
//把新添加的元素作为栈顶节点(栈顶)
Node<T> newNode = new Node<T>(item);
//当前top交给下一个节点
newNode.Next = top;
// 新节点占领top
top = newNode;
count++;
}
}
}
测试
using System;
using System.Collections.Generic;
namespace _02_StackTest
{
class Program
{
static void Main(string[] args)
{
//使用链栈
IStackDS<char> stack = new LinkStack<char>();
stack.Push('a');
stack.Push('b');
stack.Push('c');
Console.WriteLine("push a b c 之后的数据个数:" + stack.Count);
char temp = stack.Pop();
Console.WriteLine("Pop之后,栈顶数据为"+temp);
Console.WriteLine("Pop之后,栈中数据个数为"+stack.Count);
//取得栈顶数据后不删除
char temp2 = stack.Peek();
Console.WriteLine("Peek之后得到的数据是"+temp2);
Console.WriteLine("Peek之后栈中数据的个数"+stack.Count);
Console.ReadKey();
}
}
}
打印结果:
push a b c 之后的数据个数:3
Pop之后,栈顶数据为c
Pop之后,栈中数据个数为2
Peek之后得到的数据是b
Peek之后栈中数据的个数2