栈的链式存储结构
栈的链式存储结构,简称为链栈。
栈因为只是栈顶来做插入和删除操作,所以比较好的方法是将栈顶放在单链表的头部,栈顶指针和单链表的指针合二为一。
描述一下存储过程,当来了一个新的元素newNode,我们让它先指向下一个元素,即原来的栈顶元素,使用newNode.Next=top,然后让top指向新的元素newNode,使用top = newNode
链栈的方法实现:LinkStack.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace 栈
{
class LinkStack<T> : IStackDS<T>
{
private Node<T> top;//栈顶元素结点
private int count = 0;//定义栈中元素的个数,因为每次想得到元素的个数都要遍历的话太浪费时间了
//取得栈中元素的个数
public int Count
{
get { return count; }
}
//清空栈中所有的数据
public void Clear()
{
count = 0;
top = null;
}
//取得栈中元素的个数
public int GetLength()
{
return count;
}
//判断栈中是否有数据
public bool IsEmpty()
{
return count == 0;
}
//取得栈顶的元素,不删除栈顶
public T Peek()
{
return top.Data;//由于data在Node类中是私有的,所以是用我们定义的属性get,set方法去取值
}
//出栈,取得栈顶元素,然后删除
public T Pop()
{
T data = top.Data;
top = top.Next;//top指向栈顶的下一个元素,当前栈顶的元素没有人引用,就会自动销毁,删除栈顶元素
count--;
return data;
}
//入栈
public void Push(T item)
{
//把新添加的元素作为头结点,也就是栈顶元素
Node<T> newNode=new Node<T>(item);
newNode.Next = top;//新节点的下一个指的是之前添加的头结点元素
top = newNode;//头结点更新
count++;
}
}
}
Program.cs
using System;
using System.Collections;
using System.Collections.Generic;
namespace 栈
{
class Program
{
static void Main(string[] args)
{
//1.使用BCL中的Stack<T>
//Stack<char> stack=new Stack<char>();
//2.使用我们自己的栈
//IStackDS<char> stack=new SeqStack<char>(30);
//3.使用我们自己的链栈
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);
stack.Clear();
Console.WriteLine("clear之后的数据个数为:" + stack.Count);
//Console.WriteLine("空栈的时候,取得栈顶的值:" + stack.Peek());//出现异常
//当空栈的时候,不要进行pop或者peek操作,否则会出现异常
Console.ReadKey();
}
}
}
Node类:Node.cs
using DocumentFormat.OpenXml.Drawing.Charts;
using System;
using System.Collections.Generic;
using System.Text;
namespace 栈
{
/// <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)//给data赋值的构造方法
{
this.data = data;
next = null;
}
public Node(T data, Node<T> next)//这个构造方法用来给data和next同时赋值
{
this.data = data;
next= null;
}
public Node(Node<T> next)//这个构造方法用来给next赋值
{
this.next = next;
data = default(T);//data没有赋值所以给它一个默认值
}
//需要在外部进行修改,所以定义属性
public T Data
{
get { return data; }
set { data = value; }
}
public Node<T> Next
{
get { return next; }
set { next = value; }
}
}
}
实现栈的接口:IStackDS.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace 栈
{
interface IStackDS<T>
{
int Count { get; }//得到数据数量
int GetLength();
bool IsEmpty();
void Clear();
void Push(T item);
T Pop();
T Peek();
}
}
运行结果: