和之前文章数组栈类似。
1.定义栈接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 数组栈
{
public interface IStack<E>
{
//栈中元素数量
int Count { get; }
//是否为空
bool IsEmpty { get; }
//添加
void Push(E e);
//删除
E Pop();
//查找
E Peek();
}
}
2.实现接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 数组栈;
using 链表;
namespace 链表栈
{
class LinkedList1Stack<E> : IStack<E>
{
private LinkedList1<E> list;
public LinkedList1Stack()
{
list = new LinkedList1<E>();
}
public int Count { get { return list.Count; } }
public bool IsEmpty { get { return list.IsEmpty; } }
public E Peek()
{
return list.GetFirst();
}
public E Pop()
{
return list.RemoveFirst();
}
public void Push(E e)
{
list.AddFirst(e);
}
public override string ToString()
{
return "Stack:top"+list.ToString();
}
}
}
这里给出链表底层实现的代码,之前文章有提到,我直接用呢
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 链表
{
public class LinkedList1<E>
{
//如果嵌套类 最好设为私有 (内部类)节点类
private class Node
{
public E e; //节点存储的元素
public Node next; //下一个节点的引用(指针)
public Node(E e, Node next)
{
this.e = e;
this.next = next;
}
public Node(E e)
{
this.e = e;
this.next = null;
}
public override string ToString()
{
return e.ToString();
}
}
private Node head; //节点头部
private int N; //链表中有多少元素
public LinkedList1()
{
head = null;
N = 0;
}
//链表中有多少元素
public int Count
{ get { return N; } }
//链表是否为空
public bool IsEmpty
{ get { return N==0; } }
//为链表添加元素
public void Add(int index, E e)
{
if (index < 0 || index > N)
throw new ArgumentNullException("非法索引");
//如果给链表头部添加元素
if (index == 0)
{
//Node node = new Node(e);
//node.next = head;
//head = node;
//上面三段和下面这个同等
head = new Node(e, head);
}
else
{
Node pre = head;
for (int i = 0; i < index-1; i++)
{
pre = pre.next;
}
//Node node = new Node(e);
//node.next = pre.next;
//pre.next = node;
pre.next = new Node(e, pre.next);
}
N++;
}
public void AddFirst(E e)
{
Add(0, e);
}
public void AddLast(E e)
{
Add(N, e);
}
/// <summary>
/// 查找指定下标的元素
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public E Get(int index)
{
if (index < 0 || index > N)
throw new ArgumentNullException("非法索引");
Node cur = head;
for (int i = 0; i < index; i++)
{
cur = cur.next;
}
return cur.e;
}
public E GetFirst()
{
return Get(0);
}
/// <summary>
/// 返回最后一个元素
/// </summary>
/// <returns></returns>
public E GetLast()
{
return Get(N - 1);
}
//指定位置元素修改新的元素
public void Set(int index ,E newE)
{
if (index < 0 || index > N)
throw new ArgumentNullException("非法索引");
Node cur = head;
for (int i = 0; i < index; i++)
{
cur = cur.next;
}
cur.e = newE;
}
//查找链表中是否有该元素
public bool Contains(E e)
{
Node cur = head;
//链表末端为null
while (cur != null)
{
//如果存在 就返回
if (cur.e.Equals(e))
{
return true;
}
//不存在就遍历下一个
cur= cur.next;
}
//如果遍历完还没有 就返回假
return false;
}
/// <summary>
/// 删除指定位置的链表元素
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public E RemobeAt(int index)
{
if (index < 0 || index >= N)
{
throw new ArgumentException("非法索引");
}
if (index == 0)
{
Node delNode = head;
head = head.next;
N--;
return delNode.e;
}
else
{
Node pre = head;
for (int i = 0; i < index-1; i++)
{
pre = pre.next;
}
Node delNode = pre.next;
pre.next = delNode.next;
N--;
return delNode.e;
}
}
public E RemoveFirst()
{
return RemobeAt(0);
}
public E RemoveLast()
{
return RemobeAt(N-1);
}
//通过指定元素删除节点
public void Remove(E e)
{
//判断节点是否为空
if (head == null)
return;
//如果存在头元素里
if (head.e.Equals(e))
{
//进行删除 让头元素指向下一个位置。 系统会自动回收未被用到的节点
head = head.next;
N--;
}
else
{
Node cur = head;
Node pre = null;
while (cur != null)
{
if (cur.e.Equals(e))
{
break;
}
pre = cur; //存储上个节点的位置
cur = cur.next;
}
if (cur != null)
{
//pre下一个节点指向下一个下一个节点 跨过找到的元素节点
pre.next = pre.next.next;
N--;
}
}
}
//打印链表
public override string ToString()
{
StringBuilder res = new StringBuilder();
Node cur = head;
while (cur != null)
{
res.Append(cur+"->");
cur = cur.next;
}
res.Append("Null");
return res.ToString();
}
}
}
一切准备就绪,Main方法调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
namespace 链表栈
{
class Program
{
static void Main(string[] args)
{
LinkedList1Stack<int> stack = new LinkedList1Stack<int>();
//进栈
for (int i = 0; i < 5; i++)
{
stack.Push(i);
WriteLine(stack);
}
//出栈
for (int i = 0; i < 5; i++)
{
stack.Pop();
WriteLine(stack);
}
Read();
}
}
}
这里添加删除和数组栈恰恰相反,数组栈是对尾部操作,链表栈是对头部操作,这样二者时间复杂度都是最小为O(1)
结果: