首先看链表节点SingleLinkedNode<T>
[Serializable]
public class SingleLinkedNode<T> : ICloneable
{
public T Data { get; set; }
public SingleLinkedNode<T> Next { get; set; }
public SingleLinkedNode()
{
Data = default(T);
Next = null;
}
public SingleLinkedNode(T data)
{
Data = data;
Next = null;
}
public SingleLinkedNode(T data, SingleLinkedNode<T> node)
{
Data = data;
Next = node;
}
/// <summary>
/// 浅克隆
/// </summary>
/// <returns></returns>
public object Clone()
{
return this.MemberwiseClone();
}
/// <summary>
/// 深克隆
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public SingleLinkedNode<T> DeepClone<T>()
{
object obj = null;
// 将对象序列化成内存中的二进制流
BinaryFormatter binaryFormatter = new BinaryFormatter();
using MemoryStream memoryStream = new MemoryStream();
binaryFormatter.Serialize(memoryStream, this);
// 将二进制流反序列成对象
using MemoryStream memoryStream2 = new MemoryStream(memoryStream.ToArray());
BinaryFormatter binaryFormatter2 = new BinaryFormatter();
obj = binaryFormatter2.Deserialize(memoryStream2);
return (SingleLinkedNode<T>)obj;
}
public override bool Equals(object? obj)
{
// 判断是否为引用相等
if (ReferenceEquals(this, obj))
return true;
if (obj == null || this == null)
return false;
SingleLinkedNode<T> tempNode = obj as SingleLinkedNode<T>;
if (tempNode == null)
return false;
return this.GetHashCode() == tempNode.GetHashCode();
}
public override int GetHashCode()
{
return (this.Data, this.Next).GetHashCode();
}
public static bool operator == (SingleLinkedNode<T> first, SingleLinkedNode<T> second)
{
// 判断是否为引用相等
if (ReferenceEquals(first, second))
return true;
return first.Equals(second);
}
public static bool operator !=(SingleLinkedNode<T> first, SingleLinkedNode<T> second)
{
// 判断是否为引用相等
if (ReferenceEquals(first, second))
return false;
return !first.Equals(second);
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine(this.Data?.ToString());
SingleLinkedNode<T> tempNode = this.Next;
while (tempNode != null)
{
stringBuilder.AppendLine(tempNode.Data.ToString());
tempNode = tempNode.Next;
}
string ads=stringBuilder.ToString();
return stringBuilder.ToString();
}
}
类上面加上 [Serializable]的目的是为了后面的深克隆 。
接着看单链表接口方法:
/// <summary>
/// 单向链表
/// </summary>
public interface ISingleLinked<T>
{
/// <summary>
/// 第一个节点
/// </summary>
SingleLinkedNode<T> First { get; }
/// <summary>
/// 最后一个节点
/// </summary>
SingleLinkedNode<T> Last { get; }
/// <summary>
/// 链表数量
/// </summary>
int Count { get; }
/// <summary>
/// 链表是否为空
/// </summary>
bool IsEmpty { get; }
/// <summary>
/// 清空链表
/// </summary>
void Clear();
/// <summary>
/// 链表中是否包含该数据(对象比较必须重写Equals)
/// </summary>
/// <param name="value">验证数据项</param>
/// <returns></returns>
bool Contains(T value);
/// <summary>
/// 添加一个节点到节点起点
/// </summary>
/// <param name="value">节点数据</param>
/// <returns>返回Node节点</returns>
SingleLinkedNode<T> AddFirst(T value);
/// <summary>
/// 添加一个节点到节点起点
/// </summary>
/// <param name="node">需要添加的节点</param>
/// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
SingleLinkedNode<T> AddFirst(SingleLinkedNode<T> node);
/// <summary>
/// 添加一个节点到链表最后
/// </summary>
/// <param name="value">节点数据</param>
/// <returns>节点</returns>
SingleLinkedNode<T> AddLast(T value);
///<summary>
/// 添加一个节点到链表最后
/// </summary>
/// <param name="node">需要添加的节点</param>
/// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
SingleLinkedNode<T> AddLast(SingleLinkedNode<T> node);
/// <summary>
/// 插入一个节点到指定的下标出
/// </summary>
/// <param name="value">节点数据</param>
/// <param name="index">插入下标</param>
/// <returns>新增节点</returns>
SingleLinkedNode<T> Insert(T value, int index);
/// <summary>
/// 插入一个节点到指定的下标出
/// </summary>
/// <param name="node">节点</param>
/// <param name="index">插入下标</param>
/// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
SingleLinkedNode<T> Insert(SingleLinkedNode<T> node, int index);
/// <summary>
/// 删除节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>是否删除成功</returns>
bool Delete(T value);
/// <summary>
/// 删除节点
/// </summary>
/// <param name="index">删除的节点下标</param>
/// <returns>是否删除成功</returns>
bool DeleteAt(int index);
/// <summary>
/// 删除节点
/// </summary>
/// <param name="index">删除的节点</param>
/// <returns>是否删除成功</returns>
bool Delete(SingleLinkedNode<T> node);
/// <summary>
/// 删除第一个节点
/// </summary>
/// <returns>是否删除成功</returns>
bool DeleteFirst();
/// <summary>
/// 删除最后一个节点
/// </summary>
/// <returns>是否删除成功</returns>
bool DeleteLast();
/// <summary>
/// 根据数据查找节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>节点</returns>
SingleLinkedNode<T> Find(T value);
/// <summary>
/// 根据数据查找节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>节点</returns>
SingleLinkedNode<T> Find(Func<SingleLinkedNode<T>, bool> func);
/// <summary>
/// 根据数据查找上一个节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>节点</returns>
SingleLinkedNode<T> FindPrevious(T value);
/// <summary>
/// 索引器取数据
/// </summary>
/// <param name="index">下标</param>
/// <returns></returns>
T this[int index] { get; }
/// <summary>
/// 根据下标取数据
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
T GetElement(int index);
/// <summary>
/// 根据数据获取下标
/// </summary>
/// <param name="value">数据</param>
/// <returns>数据节点下标</returns>
int IndexOf(T value);
/// <summary>
/// 转数组
/// </summary>
/// <returns></returns>
T[] ToArray();
}
最后看具体实现:
/// <summary>
/// 单向链表
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingleLinked<T> : ISingleLinked<T>
{
/// <summary>
/// 头节点
/// </summary>
private SingleLinkedNode<T> _first = null;
/// <summary>
/// 尾节点
/// </summary>
private SingleLinkedNode<T> _last = null;
public T this[int index]
{
get
{
if (index >= Count || index < 0)
return default(T);
var tempNode = _first;
for (int i = 0; i < index; i++)
{
tempNode = tempNode.Next;
}
return tempNode.Data;
}
}
public SingleLinkedNode<T> First => _first;
public SingleLinkedNode<T> Last => _last;
public int Count
{
get
{
int tempCount = 0;
SingleLinkedNode<T> tempNode = _first;
while (tempNode != null)
{
tempCount++;
tempNode = tempNode.Next;
}
return tempCount;
}
}
public bool IsEmpty => _first == null;
public SingleLinkedNode<T> AddFirst(T value)
{
var tempNode = new SingleLinkedNode<T>(value);
if (_first == null)
(_first, _last) = (tempNode, tempNode);
else
{
tempNode.Next = _first;
_first = tempNode;
}
return tempNode;
}
public SingleLinkedNode<T> AddFirst(SingleLinkedNode<T> node)
{
SingleLinkedNode<T> tempNode = node.DeepClone<T>();
tempNode.Next = null;
if (_first == null)
(_first, _last) = (node, node);
else
{
node.Next = _first;
_first = node;
}
return tempNode;
}
public SingleLinkedNode<T> AddLast(T value)
{
var tempNode = new SingleLinkedNode<T>(value);
if(_first==null)
(_first, _last) = (tempNode, tempNode);
else
(_last.Next, _last) = (tempNode, tempNode);
return tempNode;
}
public SingleLinkedNode<T> AddLast(SingleLinkedNode<T> node)
{
SingleLinkedNode<T> tempNode = node.DeepClone<T>();
tempNode.Next = null;
if (_first == null)
(_first, _last) = (tempNode, tempNode);
else
(_last.Next, _last) = (tempNode, tempNode);
return tempNode;
}
public void Clear()
{
(_first, _last) = (null, null);
}
public bool Contains(T value)
{
SingleLinkedNode<T> tempNode = _first;
while (tempNode != null)
{
if (tempNode.Data.Equals(value))
return true;
tempNode = tempNode.Next;
}
return false;
}
public bool Delete(T value)
{
if (_first == null)
return false;
SingleLinkedNode<T> tempNode = _first;
if (tempNode.Data.Equals(value))
{
_first = _first.Next;
return true;
}
SingleLinkedNode<T> tempPrevious = null;
while (tempNode.Next != null)
{
tempPrevious = tempNode;
tempNode = tempNode.Next;
if (tempNode.Data.Equals(value))
{
tempPrevious.Next = tempNode.Next;
return true;
}
}
return false;
}
public bool Delete(SingleLinkedNode<T> node)
{
if (_first == null)
return false;
SingleLinkedNode<T> tempNode = _first;
if (tempNode.Equals(node))
{
_first = _first.Next;
return true;
}
SingleLinkedNode<T> tempPrevious = null;
while (tempNode.Next != null)
{
tempPrevious = tempNode;
tempNode = tempNode.Next;
if (tempNode.Equals(node))
{
tempPrevious.Next = tempNode.Next;
return true;
}
}
return false;
}
public bool DeleteAt(int index)
{
if (index < 0 || index >= Count)
return false;
if (index == 0)
{
_first = _first.Next;
return true;
}
SingleLinkedNode<T> tempNode = _first;
for (int i = 0; i < index - 1; i++)
{
tempNode = tempNode.Next;
}
tempNode.Next = tempNode.Next.Next;
return true;
}
public bool DeleteFirst()
{
if (_first == null)
return false;
_first = _first.Next;
return true;
}
public bool DeleteLast()
{
if (_first == null)
return false;
if(_first.Equals(_last))
(_first, _last) = (null, null);
SingleLinkedNode<T> tempNode = _first;
SingleLinkedNode<T> tempPrevious = null;
while (tempNode.Next != null)
{
tempPrevious = tempNode;
tempNode = tempNode.Next;
}
tempPrevious.Next = null;
_last = tempPrevious;
return true;
}
public SingleLinkedNode<T> Find(T value)
{
if (_first == null)
return _first;
SingleLinkedNode<T> tempNode = _first;
if (tempNode.Data.Equals(value))
return tempNode;
while (tempNode != null)
{
if (tempNode.Data.Equals(value))
return tempNode;
tempNode = tempNode.Next;
}
return null;
}
public SingleLinkedNode<T> Find(Func<SingleLinkedNode<T>, bool> func)
{
if (_first == null)
return _first;
SingleLinkedNode<T> tempNode = _first;
if (func(tempNode))
return tempNode;
while (tempNode != null)
{
if (func(tempNode))
return tempNode;
tempNode = tempNode.Next;
}
return null;
}
public SingleLinkedNode<T> FindPrevious(T value)
{
if (this._first == null)
return null ;
SingleLinkedNode<T> tempNode = _first;
if (tempNode.Data.Equals(value))
return null;
SingleLinkedNode<T> tempPrevious = null;
while (tempNode.Next!=null)
{
tempPrevious = tempNode;
tempNode = tempNode.Next;
if (tempNode.Data.Equals(value))
return tempPrevious;
}
return null;
}
public T GetElement(int index)
{
if (index < 0 || index >= Count)
return default(T);
if (index == 0)
return _first.Data;
SingleLinkedNode<T> tempNode = _first;
for (int i = 0; i < index; i++)
{
tempNode = tempNode.Next;
}
return tempNode.Data;
}
public int IndexOf(T value)
{
int tempIndex = 0;
SingleLinkedNode<T> tempNode = _first;
while (tempNode != null)
{
if (tempNode.Data.Equals(value))
{
return tempIndex;
}
tempNode = tempNode.Next;
tempIndex++;
}
return -1;
}
public SingleLinkedNode<T> Insert(T value, int index)
{
if (index < 0 || index > Count)
return null;
if(index==0)
return AddFirst(value);
else if(index==Count)
return AddLast(value);
else
{
if (_first == null)
return null;
SingleLinkedNode<T> tempNode = _first;
for (int i = 0; i < index - 1; i++)
{
tempNode = tempNode.Next;
}
SingleLinkedNode<T> newNode = new SingleLinkedNode<T>(value,tempNode.Next);
tempNode.Next = newNode;
return newNode;
}
}
public SingleLinkedNode<T> Insert(SingleLinkedNode<T> node, int index)
{
if (index < 0 || index > Count)
return null;
if (index == 0)
return AddFirst(node);
else if (index == Count)
return AddLast(node);
else
{
if (_first == null)
return null;
SingleLinkedNode<T> tempNode = _first;
for (int i = 0; i < index - 1; i++)
{
tempNode = tempNode.Next;
}
SingleLinkedNode<T> newNode = node.DeepClone<T>();
newNode.Next = tempNode.Next;
tempNode.Next = newNode;
return newNode;
}
}
public T[] ToArray()
{
T[] array = new T[this.Count];
SingleLinkedNode<T> tempNode = _first;
int index = 0;
while(tempNode!=null)
{
array[index++] = tempNode.Data;
tempNode = tempNode.Next;
}
return array;
}
public override string ToString()
{
return this._first.ToString();
}
}
若有错误欢迎指正,需要实现其它功能欢迎留言.